Project

General

Profile

« Previous | Next » 

Revision e06e1b7e

Added by Leszek Koltunski about 4 years ago

- after some time using it, request an App review
- some tweaking for the way the objects look (set internal_color to something slightly lighter than pure black, round the corners of the stickers better)
- set internal_node ratio to 1.42, this way the objects never get cut

View differences:

build.gradle
37 37
    implementation fileTree(dir: 'libs', include: ['*.jar'])
38 38
    implementation 'com.google.firebase:firebase-analytics:17.5.0'
39 39
    implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
40
    implementation 'com.google.android.play:core:1.8.2'
40 41

  
41 42
    api project(':distorted-library')
42 43
    implementation 'androidx.appcompat:appcompat:1.2.0'
src/main/java/org/distorted/main/RubikPreRender.java
24 24
import android.content.res.Resources;
25 25
import android.os.Bundle;
26 26

  
27
import androidx.annotation.NonNull;
28

  
29
import com.google.android.play.core.review.ReviewInfo;
30
import com.google.android.play.core.review.ReviewManager;
31
import com.google.android.play.core.review.ReviewManagerFactory;
32
import com.google.android.play.core.tasks.OnCompleteListener;
33
import com.google.android.play.core.tasks.OnFailureListener;
34
import com.google.android.play.core.tasks.Task;
27 35
import com.google.firebase.analytics.FirebaseAnalytics;
28 36

  
29 37
import org.distorted.dialogs.RubikDialogNewRecord;
......
58 66
  private long[] mEffectID;
59 67
  private boolean mIsNewRecord;
60 68
  private long mNewRecord;
61
  private int mScreenWidth, mScreenHeight;
69
  private int mScreenWidth;
62 70
  private SharedPreferences mPreferences;
63 71
  private int[][] mNextMoves;
64 72
  private TwistyObject mOldObject, mNewObject;
......
92 100
    mOldObject = null;
93 101
    mNewObject = null;
94 102

  
95
    mScreenWidth = mScreenHeight = 0;
103
    mScreenWidth = 0;
96 104
    mScrambleObjectNum = 0;
97 105

  
98 106
    mEffectID = new long[BaseEffect.Type.LENGTH];
......
352 360
      }
353 361
    }
354 362

  
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

  
365
  private void requestReview()
366
    {
367
    final RubikScores scores = RubikScores.getInstance();
368
    int numRuns   = scores.getNumRuns();
369
    int numPlay   = scores.getNumPlays();
370
    int numReview = scores.getNumReviews();
371

  
372
    if( numRuns>=2 && numPlay>6 && numReview<1 )
373
      {
374
      final RubikActivity act = (RubikActivity)mView.getContext();
375
      final ReviewManager manager = ReviewManagerFactory.create(act);
376
      Task<ReviewInfo> request = manager.requestReviewFlow();
377

  
378
      request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
379
        {
380
        @Override
381
        public void onComplete (@NonNull Task<ReviewInfo> task)
382
          {
383
          if (task.isSuccessful())
384
            {
385
            final String name = scores.getName();
386
            scores.incrementNumReviews();
387
            ReviewInfo reviewInfo = task.getResult();
388
            Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
389

  
390
            flow.addOnFailureListener(new OnFailureListener()
391
              {
392
              @Override
393
              public void onFailure(Exception e)
394
                {
395
                analyticsReport(act,"Review Flow Failed", name);
396
                }
397
              });
398

  
399
            flow.addOnCompleteListener(new OnCompleteListener<Void>()
400
              {
401
              @Override
402
              public void onComplete(@NonNull Task<Void> task)
403
                {
404
                analyticsReport(act,"Review Flow Complete", name);
405
                }
406
              });
407
            }
408
          else
409
            {
410
            String name = scores.getName();
411
            analyticsReport(act,"Request review flow not successful", name);
412
            }
413
          }
414
        });
415
      }
416
    }
417

  
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

  
420
  private void analyticsReport(RubikActivity act, String message, String name)
421
    {
422
    if( BuildConfig.DEBUG )
423
       {
424
       android.util.Log.d("pre", message);
425
       android.util.Log.d("pre", name);
426
       }
427
    else
428
      {
429
      FirebaseAnalytics analytics = act.getAnalytics();
430

  
431
      if( analytics!=null )
432
        {
433
        Bundle bundle = new Bundle();
434
        bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, message);
435
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
436
        analytics.logEvent(FirebaseAnalytics.Event.CAMPAIGN_DETAILS, bundle);
437
        }
438
      }
439
    }
440

  
355 441
///////////////////////////////////////////////////////////////////////////////////////////////////
356 442
//
357 443
///////////////////////////////////////////////////////////////////////////////////////////////////
358 444

  
359
  void setScreenSize(int width, int height)
445
  void setScreenSize(int width)
360 446
    {
361 447
    if( mNewObject!=null )
362 448
      {
......
364 450
      mNewObject.recomputeScaleFactor(width);
365 451
      }
366 452

  
367
    mScreenHeight = height;
368 453
    mScreenWidth  = width;
369 454
    }
370 455

  
......
587 672
              bundle.putLong("time", mNewRecord );
588 673

  
589 674
              reportRecord();
675
              requestReview();
590 676

  
591 677
              if( mIsNewRecord )
592 678
                {
src/main/java/org/distorted/main/RubikRenderer.java
114 114
      {
115 115
      mScreen.resize(width,height);
116 116
      mView.setScreenSize(width,height);
117
      mView.getPreRender().setScreenSize(width,height);
117
      mView.getPreRender().setScreenSize(width);
118 118
      }
119 119

  
120 120
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/TwistyDino.java
209 209
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left)
210 210
    {
211 211
    float F = 0.5f;
212
    float R = 0.035f;
212
    float R = 0.032f;
213 213
    float S = 0.05f;
214 214
    float[] vertices = { -F,F/3, 0,-2*F/3, +F,F/3 };
215 215

  
src/main/java/org/distorted/objects/TwistyHelicopter.java
200 200

  
201 201
  float getScreenRatio()
202 202
    {
203
    return 1.5f;
203
    return 1.6f;
204 204
    }
205 205

  
206 206
///////////////////////////////////////////////////////////////////////////////////////////////////
......
287 287

  
288 288
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left)
289 289
    {
290
    float R = 0.025f;
290
    float R = 0.023f;
291 291
    float S = 0.035f;
292 292
    float E = 0.5f;
293 293
    float[] vertices = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
src/main/java/org/distorted/objects/TwistyObject.java
64 64
  static final int COLOR_PINK   = 0xffff90ff;
65 65
  static final int COLOR_VIOLET = 0xff7700bb;
66 66

  
67
  private static final float NODE_RATIO = 1.32f;
67
  private static final float NODE_RATIO = 1.42f;
68 68
  private static final float MAX_SIZE_CHANGE = 1.4f;
69 69
  private static final float MIN_SIZE_CHANGE = 0.8f;
70 70

  
71 71
  private static boolean mCreateFromDMesh = true;
72 72

  
73 73
  private static final Static3D CENTER = new Static3D(0,0,0);
74
  static final int INTERIOR_COLOR = 0xff000000;
74
  static final int INTERIOR_COLOR = 0xff171717;
75 75
  private static final int POST_ROTATION_MILLISEC = 500;
76 76
  static final int TEXTURE_HEIGHT = 256;
77 77

  
src/main/java/org/distorted/objects/TwistySkewb.java
253 253

  
254 254
    if( face<COLORS )
255 255
      {
256
      float R = 0.025f;
256
      float R = 0.023f;
257 257
      float S = 0.035f;
258 258
      float E = 0.5f;
259 259
      float[] vertices = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
src/main/java/org/distorted/scores/RubikScores.java
46 46
  private boolean mNameIsVerified;
47 47
  private int mNumRuns;
48 48
  private int mNumPlays;
49
  private int mNumReviews;
49 50
  private int mDeviceID;
50 51

  
51 52
///////////////////////////////////////////////////////////////////////////////////////////////////
......
68 69

  
69 70
    mNameIsVerified = false;
70 71

  
71
    mNumPlays= -1;
72
    mNumRuns = -1;
73
    mDeviceID= -1;
72
    mNumPlays   = -1;
73
    mNumRuns    = -1;
74
    mDeviceID   = -1;
75
    mNumReviews =  0;
74 76
    }
75 77

  
76 78
///////////////////////////////////////////////////////////////////////////////////////////////////
......
94 96
    }
95 97

  
96 98
///////////////////////////////////////////////////////////////////////////////////////////////////
97
// PUBLIC API
99

  
100
  synchronized void successfulSubmit()
101
    {
102
    mNameIsVerified = true;
103

  
104
    for(int i=0; i<NUM_OBJECTS; i++)
105
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
106
        for(int k=0; k<MAX_LEVEL; k++)
107
          {
108
          mSubmitted[i][j][k]=1;
109
          }
110
    }
111

  
98 112
///////////////////////////////////////////////////////////////////////////////////////////////////
99 113

  
100
  public static RubikScores getInstance()
114
  int getDeviceID()
101 115
    {
102
    if( mThis==null )
103
      {
104
      mThis = new RubikScores();
105
      }
116
    return mDeviceID;
117
    }
106 118

  
107
    return mThis;
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  boolean isVerified()
122
    {
123
    return mNameIsVerified;
108 124
    }
109 125

  
110 126
///////////////////////////////////////////////////////////////////////////////////////////////////
111 127

  
112
  public synchronized void savePreferences(SharedPreferences.Editor editor)
128
  synchronized boolean thereAreUnsubmittedRecords()
113 129
    {
114
    StringBuilder builder = new StringBuilder();
115 130
    ObjectList list;
116
    int[] sizes;
117 131
    int length;
118 132

  
119
    for(int level=0; level<MAX_LEVEL; level++)
133
    for(int object=0; object<NUM_OBJECTS; object++)
120 134
      {
121
      builder.setLength(0);
122

  
123
      for(int object=0; object<NUM_OBJECTS; object++)
124
        {
125
        list = ObjectList.getObject(object);
126
        sizes = list.getSizes();
127
        length = sizes.length;
135
      list = ObjectList.getObject(object);
136
      length = list.getSizes().length;
128 137

  
129
        for(int size=0; size<length; size++)
138
      for(int size=0; size<length; size++)
139
        for(int level=0; level<MAX_LEVEL; level++)
130 140
          {
131
          builder.append(list.name());
132
          builder.append("_");
133
          builder.append(sizes[size]);
134
          builder.append("=");
135
          builder.append(mRecords[object][size][level]);
136
          builder.append(",");
137
          builder.append(mSubmitted[object][size][level]);
138
          builder.append(" ");
141
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
142
            {
143
            return true;
144
            }
139 145
          }
140
        }
141

  
142
      editor.putString("scores_record"+level, builder.toString());
143 146
      }
144 147

  
145
    editor.putString("scores_name"  , mName  );
146
    editor.putBoolean("scores_isVerified", mNameIsVerified);
147
    editor.putInt("scores_numPlays", mNumPlays);
148
    editor.putInt("scores_numRuns" , mNumRuns);
149
    editor.putInt("scores_deviceid", mDeviceID);
148
    return false;
150 149
    }
151 150

  
152 151
///////////////////////////////////////////////////////////////////////////////////////////////////
153 152

  
154
  public synchronized void restorePreferences(SharedPreferences preferences)
153
  synchronized String getRecordList(String strObj, String strLvl, String strTim)
155 154
    {
156
    String recordStr, subStr, nameStr, sizeStr, timeStr, submStr;
157
    int start, end, equals, underscore, comma;
158
    int object, sizeIndex, subm;
159
    long time;
155
    ObjectList list;
156
    StringBuilder builderObj = new StringBuilder();
157
    StringBuilder builderLvl = new StringBuilder();
158
    StringBuilder builderTim = new StringBuilder();
159
    boolean first = true;
160
    int[] sizes;
161
    int length;
160 162

  
161
    for(int level=0; level<MAX_LEVEL; level++)
163
    for(int object=0; object<NUM_OBJECTS; object++)
162 164
      {
163
      start = end = 0;
164
      recordStr = preferences.getString("scores_record"+level, "");
165
      list = ObjectList.getObject(object);
166
      sizes = list.getSizes();
167
      length = sizes.length;
165 168

  
166
      while( end!=-1 )
169
      for(int size=0; size<length; size++)
167 170
        {
168
        end = recordStr.indexOf(" ", start);
169

  
170
        if( end==-1 ) subStr = recordStr.substring(start);
171
        else          subStr = recordStr.substring(start,end);
172

  
173
        start = end+1;
174

  
175
        underscore = subStr.indexOf("_");
176
        equals = subStr.indexOf("=");
177
        comma = subStr.indexOf(",");
178

  
179
        if( underscore>=0 && equals>=0 && comma>=0 )
171
        for(int level=0; level<MAX_LEVEL; level++)
180 172
          {
181
          nameStr = subStr.substring(0,underscore);
182
          sizeStr = subStr.substring(underscore+1, equals);
183
          timeStr = subStr.substring(equals+1,comma);
184
          submStr = subStr.substring(comma+1);
185

  
186
          object = ObjectList.getOrdinal(nameStr);
187

  
188
          if( object>=0 && object< NUM_OBJECTS )
173
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
189 174
            {
190
            sizeIndex = ObjectList.getSizeIndex(object,Integer.parseInt(sizeStr));
191
            time = Long.parseLong(timeStr);
192
            subm = Integer.parseInt(submStr);
193

  
194
            if( sizeIndex>=0 && sizeIndex<MAX_NUM_OBJECTS && subm>=0 && subm<=1 )
175
            if( !first )
195 176
              {
196
              mRecords  [object][sizeIndex][level] = time;
197
              mSubmitted[object][sizeIndex][level] = subm;
177
              builderObj.append(',');
178
              builderLvl.append(',');
179
              builderTim.append(',');
198 180
              }
199 181
            else
200 182
              {
201
              android.util.Log.e("scores", "error: size="+sizeIndex+" subm="+subm);
183
              first=false;
202 184
              }
203
            }
204
          else
205
            {
206
            android.util.Log.e("scores", "error: object="+object);
185

  
186
            builderObj.append(list.name());
187
            builderObj.append("_");
188
            builderObj.append(sizes[size]);
189
            builderLvl.append(level);
190
            builderTim.append(mRecords[object][size][level]);
207 191
            }
208 192
          }
209 193
        }
210 194
      }
211 195

  
212
    mName           = preferences.getString("scores_name"  , "" );
213
    mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
214
    mNumPlays       = preferences.getInt("scores_numPlays", 0);
215
    mNumRuns        = preferences.getInt("scores_numRuns" , 0);
216
    mDeviceID       = preferences.getInt("scores_deviceid",-1);
196
    return strObj+builderObj.toString()+strLvl+builderLvl.toString()+strTim+builderTim.toString();
197
    }
217 198

  
218
    if( mDeviceID==-1 ) mDeviceID = privateGetDeviceID();
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
// Public API
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

  
203
  public synchronized long getRecord(int object, int size, int level)
204
    {
205
    int maxsize = ObjectList.getObject(object).getSizes().length;
206

  
207
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
208
      {
209
      return mRecords[object][size][level];
210
      }
211

  
212
    return -1;
219 213
    }
220 214

  
221 215
///////////////////////////////////////////////////////////////////////////////////////////////////
222 216

  
223
  public synchronized boolean setRecord(int object, int size, int level, long timeTaken)
217
  public synchronized boolean isSubmitted(int object, int size, int level)
224 218
    {
225 219
    int maxsize = ObjectList.getObject(object).getSizes().length;
226 220

  
227
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=1 && level<=MAX_LEVEL )
221
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
228 222
      {
229
      if( mRecords[object][size][level-1]> timeTaken )
230
        {
231
        mRecords  [object][size][level-1] = timeTaken;
232
        mSubmitted[object][size][level-1] = 0;
233
        return true;
234
        }
223
      return mSubmitted[object][size][level]==1;
235 224
      }
236 225

  
237 226
    return false;
......
239 228

  
240 229
///////////////////////////////////////////////////////////////////////////////////////////////////
241 230

  
242
  public void incrementNumPlays()
231
  public int getNumPlays()
243 232
    {
244
    mNumPlays++;
233
    return mNumPlays;
245 234
    }
246 235

  
247 236
///////////////////////////////////////////////////////////////////////////////////////////////////
248 237

  
249
  public void incrementNumRuns()
238
  public int getNumRuns()
250 239
    {
251
    mNumRuns++;
240
    return mNumRuns;
252 241
    }
253 242

  
254 243
///////////////////////////////////////////////////////////////////////////////////////////////////
255 244

  
256
  public void setName(String newName)
245
  public int getNumReviews()
257 246
    {
258
    mName = newName;
247
    return mNumReviews;
259 248
    }
260 249

  
261 250
///////////////////////////////////////////////////////////////////////////////////////////////////
262 251

  
263
  synchronized void successfulSubmit()
252
  public String getName()
264 253
    {
265
    mNameIsVerified = true;
254
    return mName;
255
    }
266 256

  
267
    for(int i=0; i<NUM_OBJECTS; i++)
268
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
269
        for(int k=0; k<MAX_LEVEL; k++)
270
          {
271
          mSubmitted[i][j][k]=1;
272
          }
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

  
259
  public String getCountry()
260
    {
261
    return mCountry;
273 262
    }
274 263

  
275 264
///////////////////////////////////////////////////////////////////////////////////////////////////
276 265

  
277
  public void setCountry(Context context)
266
  public void incrementNumPlays()
278 267
    {
279
    TelephonyManager tM =((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
268
    mNumPlays++;
269
    }
280 270

  
281
    if( tM!=null )
282
      {
283
      mCountry = tM.getSimCountryIso();
271
///////////////////////////////////////////////////////////////////////////////////////////////////
284 272

  
285
      if( mCountry==null || mCountry.length()<=1 )
286
        {
287
        mCountry = tM.getNetworkCountryIso();
288
        }
289
      }
273
  public void incrementNumRuns()
274
    {
275
    mNumRuns++;
276
    }
290 277

  
291
    // Special case: Dominicana. Its ISO-3166-alpha-2 country code is 'do' which we can't have here
292
    // because we later on map this to a resource name (the flag) and 'do' is a reserved Java keyword
293
    // and can't be a resource name.
278
///////////////////////////////////////////////////////////////////////////////////////////////////
294 279

  
295
    if( mCountry.equals("do") ) mCountry = "dm";
280
  public void incrementNumReviews()
281
    {
282
    mNumReviews++;
283
    }
284

  
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

  
287
  public void setName(String newName)
288
    {
289
    mName = newName;
296 290
    }
297 291

  
298 292
///////////////////////////////////////////////////////////////////////////////////////////////////
......
320 314

  
321 315
///////////////////////////////////////////////////////////////////////////////////////////////////
322 316

  
323
  public synchronized long getRecord(int object, int size, int level)
317
  public void setCountry(Context context)
324 318
    {
325
    int maxsize = ObjectList.getObject(object).getSizes().length;
319
    TelephonyManager tM =((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
326 320

  
327
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
321
    if( tM!=null )
328 322
      {
329
      return mRecords[object][size][level];
323
      mCountry = tM.getSimCountryIso();
324

  
325
      if( mCountry==null || mCountry.length()<=1 )
326
        {
327
        mCountry = tM.getNetworkCountryIso();
328
        }
330 329
      }
331 330

  
332
    return -1;
331
    // Special case: Dominicana. Its ISO-3166-alpha-2 country code is 'do' which we can't have here
332
    // because we later on map this to a resource name (the flag) and 'do' is a reserved Java keyword
333
    // and can't be a resource name.
334

  
335
    if( mCountry.equals("do") ) mCountry = "dm";
333 336
    }
334 337

  
335 338
///////////////////////////////////////////////////////////////////////////////////////////////////
336 339

  
337
  public synchronized boolean isSubmitted(int object, int size, int level)
340
  public static RubikScores getInstance()
338 341
    {
339
    int maxsize = ObjectList.getObject(object).getSizes().length;
340

  
341
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
342
    if( mThis==null )
342 343
      {
343
      return mSubmitted[object][size][level]==1;
344
      mThis = new RubikScores();
344 345
      }
345 346

  
346
    return false;
347
    return mThis;
347 348
    }
348 349

  
349 350
///////////////////////////////////////////////////////////////////////////////////////////////////
350 351

  
351
  int getDeviceID()
352
  public synchronized void savePreferences(SharedPreferences.Editor editor)
352 353
    {
353
    return mDeviceID;
354
    }
355

  
356
///////////////////////////////////////////////////////////////////////////////////////////////////
354
    StringBuilder builder = new StringBuilder();
355
    ObjectList list;
356
    int[] sizes;
357
    int length;
357 358

  
358
  boolean isVerified()
359
    {
360
    return mNameIsVerified;
361
    }
359
    for(int level=0; level<MAX_LEVEL; level++)
360
      {
361
      builder.setLength(0);
362 362

  
363
///////////////////////////////////////////////////////////////////////////////////////////////////
363
      for(int object=0; object<NUM_OBJECTS; object++)
364
        {
365
        list = ObjectList.getObject(object);
366
        sizes = list.getSizes();
367
        length = sizes.length;
364 368

  
365
  int getNumPlays()
366
    {
367
    return mNumPlays;
368
    }
369
        for(int size=0; size<length; size++)
370
          {
371
          builder.append(list.name());
372
          builder.append("_");
373
          builder.append(sizes[size]);
374
          builder.append("=");
375
          builder.append(mRecords[object][size][level]);
376
          builder.append(",");
377
          builder.append(mSubmitted[object][size][level]);
378
          builder.append(" ");
379
          }
380
        }
369 381

  
370
///////////////////////////////////////////////////////////////////////////////////////////////////
382
      editor.putString("scores_record"+level, builder.toString());
383
      }
371 384

  
372
  int getNumRuns()
373
    {
374
    return mNumRuns;
385
    editor.putString("scores_name"  , mName  );
386
    editor.putBoolean("scores_isVerified", mNameIsVerified);
387
    editor.putInt("scores_numPlays", mNumPlays);
388
    editor.putInt("scores_numRuns" , mNumRuns);
389
    editor.putInt("scores_deviceid", mDeviceID);
390
    editor.putInt("scores_review"  , mNumReviews);
375 391
    }
376 392

  
377 393
///////////////////////////////////////////////////////////////////////////////////////////////////
378 394

  
379
  public String getName()
395
  public synchronized void restorePreferences(SharedPreferences preferences)
380 396
    {
381
    return mName;
382
    }
397
    String recordStr, subStr, nameStr, sizeStr, timeStr, submStr;
398
    int start, end, equals, underscore, comma;
399
    int object, sizeIndex, subm;
400
    long time;
383 401

  
384
///////////////////////////////////////////////////////////////////////////////////////////////////
402
    for(int level=0; level<MAX_LEVEL; level++)
403
      {
404
      start = end = 0;
405
      recordStr = preferences.getString("scores_record"+level, "");
385 406

  
386
  public String getCountry()
387
    {
388
    return mCountry;
389
    }
407
      while( end!=-1 )
408
        {
409
        end = recordStr.indexOf(" ", start);
390 410

  
391
///////////////////////////////////////////////////////////////////////////////////////////////////
411
        if( end==-1 ) subStr = recordStr.substring(start);
412
        else          subStr = recordStr.substring(start,end);
392 413

  
393
  synchronized boolean thereAreUnsubmittedRecords()
394
    {
395
    ObjectList list;
396
    int length;
414
        start = end+1;
397 415

  
398
    for(int object=0; object<NUM_OBJECTS; object++)
399
      {
400
      list = ObjectList.getObject(object);
401
      length = list.getSizes().length;
416
        underscore = subStr.indexOf("_");
417
        equals = subStr.indexOf("=");
418
        comma = subStr.indexOf(",");
402 419

  
403
      for(int size=0; size<length; size++)
404
        for(int level=0; level<MAX_LEVEL; level++)
420
        if( underscore>=0 && equals>=0 && comma>=0 )
405 421
          {
406
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
422
          nameStr = subStr.substring(0,underscore);
423
          sizeStr = subStr.substring(underscore+1, equals);
424
          timeStr = subStr.substring(equals+1,comma);
425
          submStr = subStr.substring(comma+1);
426

  
427
          object = ObjectList.getOrdinal(nameStr);
428

  
429
          if( object>=0 && object< NUM_OBJECTS )
407 430
            {
408
            return true;
431
            sizeIndex = ObjectList.getSizeIndex(object,Integer.parseInt(sizeStr));
432
            time = Long.parseLong(timeStr);
433
            subm = Integer.parseInt(submStr);
434

  
435
            if( sizeIndex>=0 && sizeIndex<MAX_NUM_OBJECTS && subm>=0 && subm<=1 )
436
              {
437
              mRecords  [object][sizeIndex][level] = time;
438
              mSubmitted[object][sizeIndex][level] = subm;
439
              }
440
            else
441
              {
442
              android.util.Log.e("scores", "error: size="+sizeIndex+" subm="+subm);
443
              }
444
            }
445
          else
446
            {
447
            android.util.Log.e("scores", "error: object="+object);
409 448
            }
410 449
          }
450
        }
411 451
      }
412 452

  
413
    return false;
453
    mName           = preferences.getString("scores_name"  , "" );
454
    mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
455
    mNumPlays       = preferences.getInt("scores_numPlays", 0);
456
    mNumRuns        = preferences.getInt("scores_numRuns" , 0);
457
    mDeviceID       = preferences.getInt("scores_deviceid",-1);
458
    mNumReviews     = preferences.getInt("scores_review"  , 0);
459

  
460
    if( mDeviceID==-1 ) mDeviceID = privateGetDeviceID();
414 461
    }
415 462

  
416 463
///////////////////////////////////////////////////////////////////////////////////////////////////
417 464

  
418
  synchronized String getRecordList(String strObj, String strLvl, String strTim)
465
  public synchronized boolean setRecord(int object, int size, int level, long timeTaken)
419 466
    {
420
    ObjectList list;
421
    StringBuilder builderObj = new StringBuilder();
422
    StringBuilder builderLvl = new StringBuilder();
423
    StringBuilder builderTim = new StringBuilder();
424
    boolean first = true;
425
    int[] sizes;
426
    int length;
467
    int maxsize = ObjectList.getObject(object).getSizes().length;
427 468

  
428
    for(int object=0; object<NUM_OBJECTS; object++)
469
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=1 && level<=MAX_LEVEL )
429 470
      {
430
      list = ObjectList.getObject(object);
431
      sizes = list.getSizes();
432
      length = sizes.length;
433

  
434
      for(int size=0; size<length; size++)
471
      if( mRecords[object][size][level-1]> timeTaken )
435 472
        {
436
        for(int level=0; level<MAX_LEVEL; level++)
437
          {
438
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
439
            {
440
            if( !first )
441
              {
442
              builderObj.append(',');
443
              builderLvl.append(',');
444
              builderTim.append(',');
445
              }
446
            else
447
              {
448
              first=false;
449
              }
450

  
451
            builderObj.append(list.name());
452
            builderObj.append("_");
453
            builderObj.append(sizes[size]);
454
            builderLvl.append(level);
455
            builderTim.append(mRecords[object][size][level]);
456
            }
457
          }
473
        mRecords  [object][size][level-1] = timeTaken;
474
        mSubmitted[object][size][level-1] = 0;
475
        return true;
458 476
        }
459 477
      }
460 478

  
461
    return strObj+builderObj.toString()+strLvl+builderLvl.toString()+strTim+builderTim.toString();
479
    return false;
462 480
    }
463 481
  }

Also available in: Unified diff