Project

General

Profile

Download (13.5 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / network / RubikScores.java @ 318c0a7d

1 f0e87514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 6a083c6a Leszek Koltunski
package org.distorted.network;
21 f0e87514 Leszek Koltunski
22 3f7a4363 Leszek Koltunski
import java.util.UUID;
23
24 82ce8e64 Leszek Koltunski
import android.content.Context;
25 f0e87514 Leszek Koltunski
import android.content.SharedPreferences;
26 82ce8e64 Leszek Koltunski
import android.telephony.TelephonyManager;
27 1c90c64a Leszek Koltunski
28 25445dcf Leszek Koltunski
import com.google.firebase.crashlytics.FirebaseCrashlytics;
29
30 318c0a7d Leszek Koltunski
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
31
import static org.distorted.objectlib.main.ObjectType.MAX_LEVEL;
32 f0e87514 Leszek Koltunski
33 318c0a7d Leszek Koltunski
import org.distorted.objectlib.main.ObjectType;
34 82ce8e64 Leszek Koltunski
35 3f7a4363 Leszek Koltunski
import org.distorted.main.BuildConfig;
36 f0e87514 Leszek Koltunski
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38 82ce8e64 Leszek Koltunski
// hold my own scores, and some other statistics.
39 f0e87514 Leszek Koltunski
40
public class RubikScores
41
  {
42 1c90c64a Leszek Koltunski
  public static final long NO_RECORD = Long.MAX_VALUE;
43 714292f1 Leszek Koltunski
  private static RubikScores mThis;
44
45 7ac0ee88 Leszek Koltunski
  private final long[][] mRecords;
46
  private final int [][] mSubmitted;
47 286d73ae Leszek Koltunski
48 82ce8e64 Leszek Koltunski
  private String mName, mCountry;
49 c3ffcf58 Leszek Koltunski
  private boolean mNameIsVerified;
50
  private int mNumRuns;
51
  private int mNumPlays;
52 59aee296 Leszek Koltunski
  private int mNumWins;
53 82ce8e64 Leszek Koltunski
  private int mDeviceID;
54 f0e87514 Leszek Koltunski
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56
57 714292f1 Leszek Koltunski
  private RubikScores()
58 f0e87514 Leszek Koltunski
    {
59 7ac0ee88 Leszek Koltunski
    mRecords   = new long[NUM_OBJECTS][MAX_LEVEL];
60
    mSubmitted = new int [NUM_OBJECTS][MAX_LEVEL];
61 f0e87514 Leszek Koltunski
62
    for(int i=0; i<NUM_OBJECTS; i++)
63 7ac0ee88 Leszek Koltunski
      for(int j=0; j<MAX_LEVEL; j++)
64
        {
65
        mRecords[i][j]   = NO_RECORD;
66
        mSubmitted[i][j] = 0;
67
        }
68 c3ffcf58 Leszek Koltunski
69 f895e77a Leszek Koltunski
    mName = "";
70 82ce8e64 Leszek Koltunski
    mCountry = "un";
71
72 c3ffcf58 Leszek Koltunski
    mNameIsVerified = false;
73 82ce8e64 Leszek Koltunski
74 59aee296 Leszek Koltunski
    mNumPlays= -1;
75
    mNumRuns = -1;
76
    mDeviceID= -1;
77
    mNumWins =  0;
78 f0e87514 Leszek Koltunski
    }
79
80 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
81
82
  private int privateGetDeviceID()
83
    {
84
    int id;
85
86
    try
87
      {
88
      String s = UUID.randomUUID().toString();
89 874c37b1 Leszek Koltunski
      id = s.hashCode();
90 17f9a695 Leszek Koltunski
      }
91
    catch(Exception ex)
92
      {
93
      id = 0;
94
      android.util.Log.e("scores", "Exception in getDeviceID()");
95
      }
96
97
    return id<0 ? -id : id;
98
    }
99
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101 e06e1b7e Leszek Koltunski
102
  synchronized void successfulSubmit()
103
    {
104
    mNameIsVerified = true;
105
106
    for(int i=0; i<NUM_OBJECTS; i++)
107 7ac0ee88 Leszek Koltunski
      for(int j=0; j<MAX_LEVEL; j++)
108
        {
109
        mSubmitted[i][j]=1;
110
        }
111 e06e1b7e Leszek Koltunski
    }
112
113 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
114
115 e06e1b7e Leszek Koltunski
  int getDeviceID()
116 714292f1 Leszek Koltunski
    {
117 e06e1b7e Leszek Koltunski
    return mDeviceID;
118
    }
119 714292f1 Leszek Koltunski
120 f0e87514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
121
122 e06e1b7e Leszek Koltunski
  synchronized boolean thereAreUnsubmittedRecords()
123 f0e87514 Leszek Koltunski
    {
124 e06e1b7e Leszek Koltunski
    for(int object=0; object<NUM_OBJECTS; object++)
125 f0e87514 Leszek Koltunski
      {
126 7ac0ee88 Leszek Koltunski
      for(int level=0; level<MAX_LEVEL; level++)
127
        {
128
        if( mSubmitted[object][level]==0 && mRecords[object][level]<NO_RECORD ) return true;
129
        }
130 f0e87514 Leszek Koltunski
      }
131 c3ffcf58 Leszek Koltunski
132 e06e1b7e Leszek Koltunski
    return false;
133 f0e87514 Leszek Koltunski
    }
134
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136
137 e06e1b7e Leszek Koltunski
  synchronized String getRecordList(String strObj, String strLvl, String strTim)
138 f0e87514 Leszek Koltunski
    {
139 e06e1b7e Leszek Koltunski
    StringBuilder builderObj = new StringBuilder();
140
    StringBuilder builderLvl = new StringBuilder();
141
    StringBuilder builderTim = new StringBuilder();
142
    boolean first = true;
143 f0e87514 Leszek Koltunski
144 e06e1b7e Leszek Koltunski
    for(int object=0; object<NUM_OBJECTS; object++)
145 f0e87514 Leszek Koltunski
      {
146 318c0a7d Leszek Koltunski
      String name = ObjectType.getObject(object).name();
147 f0e87514 Leszek Koltunski
148 7ac0ee88 Leszek Koltunski
      for(int level=0; level<MAX_LEVEL; level++)
149 f0e87514 Leszek Koltunski
        {
150 7ac0ee88 Leszek Koltunski
        if( mSubmitted[object][level]==0 && mRecords[object][level]<NO_RECORD )
151 f0e87514 Leszek Koltunski
          {
152 7ac0ee88 Leszek Koltunski
          if( !first )
153 f0e87514 Leszek Koltunski
            {
154 7ac0ee88 Leszek Koltunski
            builderObj.append(',');
155
            builderLvl.append(',');
156
            builderTim.append(',');
157
            }
158
          else
159
            {
160
            first=false;
161 f0e87514 Leszek Koltunski
            }
162 7ac0ee88 Leszek Koltunski
163
          builderObj.append(name);
164
          builderLvl.append(level);
165
          builderTim.append(mRecords[object][level]);
166 f0e87514 Leszek Koltunski
          }
167
        }
168
      }
169 c3ffcf58 Leszek Koltunski
170 e06e1b7e Leszek Koltunski
    return strObj+builderObj.toString()+strLvl+builderLvl.toString()+strTim+builderTim.toString();
171
    }
172 82ce8e64 Leszek Koltunski
173 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
174
// Public API
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177 7ac0ee88 Leszek Koltunski
  public synchronized long getRecord(int obj, int level)
178 e06e1b7e Leszek Koltunski
    {
179 7ac0ee88 Leszek Koltunski
    return (obj>=0 && obj<NUM_OBJECTS && level>=0 && level<MAX_LEVEL) ? mRecords[obj][level] : -1;
180 f0e87514 Leszek Koltunski
    }
181
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183
184 7ac0ee88 Leszek Koltunski
  public synchronized boolean isSubmitted(int obj, int level)
185 f0e87514 Leszek Koltunski
    {
186 7ac0ee88 Leszek Koltunski
    return obj>=0 && obj<NUM_OBJECTS && level>=0 && level<MAX_LEVEL && mSubmitted[obj][level]==1;
187 f0e87514 Leszek Koltunski
    }
188 714292f1 Leszek Koltunski
189 ee4e7896 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
190
191
  public boolean isVerified()
192
    {
193
    return mNameIsVerified;
194
    }
195
196 c3ffcf58 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
197
198 e06e1b7e Leszek Koltunski
  public int getNumPlays()
199 c3ffcf58 Leszek Koltunski
    {
200 e06e1b7e Leszek Koltunski
    return mNumPlays;
201 c3ffcf58 Leszek Koltunski
    }
202
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
205 e06e1b7e Leszek Koltunski
  public int getNumRuns()
206 c3ffcf58 Leszek Koltunski
    {
207 e06e1b7e Leszek Koltunski
    return mNumRuns;
208 c3ffcf58 Leszek Koltunski
    }
209
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211
212 e06e1b7e Leszek Koltunski
  public String getName()
213 c3ffcf58 Leszek Koltunski
    {
214 e06e1b7e Leszek Koltunski
    return mName;
215
    }
216 1c90c64a Leszek Koltunski
217 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
218
219
  public String getCountry()
220
    {
221
    return mCountry;
222 1c90c64a Leszek Koltunski
    }
223
224 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 e06e1b7e Leszek Koltunski
  public void incrementNumPlays()
227 286d73ae Leszek Koltunski
    {
228 e06e1b7e Leszek Koltunski
    mNumPlays++;
229
    }
230 286d73ae Leszek Koltunski
231 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
232 82ce8e64 Leszek Koltunski
233 e06e1b7e Leszek Koltunski
  public void incrementNumRuns()
234
    {
235
    mNumRuns++;
236
    }
237 82ce8e64 Leszek Koltunski
238 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
239 82ce8e64 Leszek Koltunski
240 59aee296 Leszek Koltunski
  public int incrementNumWins()
241 e06e1b7e Leszek Koltunski
    {
242 59aee296 Leszek Koltunski
    mNumWins++;
243
    return mNumWins;
244 e06e1b7e Leszek Koltunski
    }
245
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247
248
  public void setName(String newName)
249
    {
250
    mName = newName;
251 82ce8e64 Leszek Koltunski
    }
252
253 d7e539d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
254
255 7ac0ee88 Leszek Koltunski
  public synchronized boolean isSolved(int obj, int level)
256 d7e539d0 Leszek Koltunski
    {
257 7ac0ee88 Leszek Koltunski
    return obj>=0 && obj<NUM_OBJECTS && level>=0 && level<MAX_LEVEL && mRecords[obj][level]<NO_RECORD;
258 d7e539d0 Leszek Koltunski
    }
259
260 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
261
262 e06e1b7e Leszek Koltunski
  public void setCountry(Context context)
263 714292f1 Leszek Koltunski
    {
264 e06e1b7e Leszek Koltunski
    TelephonyManager tM =((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
265 714292f1 Leszek Koltunski
266 e06e1b7e Leszek Koltunski
    if( tM!=null )
267 714292f1 Leszek Koltunski
      {
268 e06e1b7e Leszek Koltunski
      mCountry = tM.getSimCountryIso();
269
270
      if( mCountry==null || mCountry.length()<=1 )
271
        {
272
        mCountry = tM.getNetworkCountryIso();
273
        }
274 714292f1 Leszek Koltunski
      }
275
276 e06e1b7e Leszek Koltunski
    // Special case: Dominicana. Its ISO-3166-alpha-2 country code is 'do' which we can't have here
277
    // because we later on map this to a resource name (the flag) and 'do' is a reserved Java keyword
278
    // and can't be a resource name.
279
280
    if( mCountry.equals("do") ) mCountry = "dm";
281 714292f1 Leszek Koltunski
    }
282 c3ffcf58 Leszek Koltunski
283 c8249cf6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
284
285
  public void setCountry(String country)
286
    {
287
    mCountry = country;
288
289
    if( mCountry.equals("do") ) mCountry = "dm";  // see above
290
    }
291
292 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294 e06e1b7e Leszek Koltunski
  public static RubikScores getInstance()
295 286d73ae Leszek Koltunski
    {
296 e06e1b7e Leszek Koltunski
    if( mThis==null )
297 286d73ae Leszek Koltunski
      {
298 e06e1b7e Leszek Koltunski
      mThis = new RubikScores();
299 286d73ae Leszek Koltunski
      }
300
301 e06e1b7e Leszek Koltunski
    return mThis;
302 286d73ae Leszek Koltunski
    }
303
304 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306 e06e1b7e Leszek Koltunski
  public synchronized void savePreferences(SharedPreferences.Editor editor)
307 17f9a695 Leszek Koltunski
    {
308 e06e1b7e Leszek Koltunski
    StringBuilder builder = new StringBuilder();
309 7ac0ee88 Leszek Koltunski
    String name;
310 1c90c64a Leszek Koltunski
311 e06e1b7e Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
312
      {
313
      builder.setLength(0);
314 1c90c64a Leszek Koltunski
315 e06e1b7e Leszek Koltunski
      for(int object=0; object<NUM_OBJECTS; object++)
316
        {
317 318c0a7d Leszek Koltunski
        name = ObjectType.getObject(object).name();
318 7ac0ee88 Leszek Koltunski
        builder.append(name);
319
        builder.append("=");
320
        builder.append(mRecords[object][level]);
321
        builder.append(",");
322
        builder.append(mSubmitted[object][level]);
323
        builder.append(" ");
324 e06e1b7e Leszek Koltunski
        }
325 c3ffcf58 Leszek Koltunski
326 e06e1b7e Leszek Koltunski
      editor.putString("scores_record"+level, builder.toString());
327
      }
328 c3ffcf58 Leszek Koltunski
329 e06e1b7e Leszek Koltunski
    editor.putString("scores_name"  , mName  );
330
    editor.putBoolean("scores_isVerified", mNameIsVerified);
331
    editor.putInt("scores_numPlays", mNumPlays);
332 59aee296 Leszek Koltunski
    editor.putInt("scores_numRuns" , mNumRuns );
333 e06e1b7e Leszek Koltunski
    editor.putInt("scores_deviceid", mDeviceID);
334 59aee296 Leszek Koltunski
    editor.putInt("scores_review"  , mNumWins );
335 c3ffcf58 Leszek Koltunski
    }
336
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
339 e06e1b7e Leszek Koltunski
  public synchronized void restorePreferences(SharedPreferences preferences)
340 c3ffcf58 Leszek Koltunski
    {
341 25445dcf Leszek Koltunski
    String recordStr, subStr, nameStr, sizeStr, timeStr, submStr, errorStr="";
342 7ac0ee88 Leszek Koltunski
    int start, end, equals, underscore, comma, object, subm;
343 e06e1b7e Leszek Koltunski
    long time;
344 25445dcf Leszek Koltunski
    boolean thereWasError = false;
345 c3ffcf58 Leszek Koltunski
346 e06e1b7e Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
347
      {
348
      start = end = 0;
349
      recordStr = preferences.getString("scores_record"+level, "");
350 c3ffcf58 Leszek Koltunski
351 e06e1b7e Leszek Koltunski
      while( end!=-1 )
352
        {
353
        end = recordStr.indexOf(" ", start);
354 4895fff6 Leszek Koltunski
355 e06e1b7e Leszek Koltunski
        if( end==-1 ) subStr = recordStr.substring(start);
356
        else          subStr = recordStr.substring(start,end);
357 4895fff6 Leszek Koltunski
358 e06e1b7e Leszek Koltunski
        start = end+1;
359 4895fff6 Leszek Koltunski
360 e06e1b7e Leszek Koltunski
        underscore = subStr.indexOf("_");
361
        equals = subStr.indexOf("=");
362
        comma = subStr.indexOf(",");
363 4895fff6 Leszek Koltunski
364 e06e1b7e Leszek Koltunski
        if( underscore>=0 && equals>=0 && comma>=0 )
365 4c0cd600 Leszek Koltunski
          {
366 e06e1b7e Leszek Koltunski
          nameStr = subStr.substring(0,underscore);
367
          sizeStr = subStr.substring(underscore+1, equals);
368
          timeStr = subStr.substring(equals+1,comma);
369
          submStr = subStr.substring(comma+1);
370
371 318c0a7d Leszek Koltunski
          object = ObjectType.getOrdinal(nameStr);
372 e06e1b7e Leszek Koltunski
373
          if( object>=0 && object< NUM_OBJECTS )
374 4895fff6 Leszek Koltunski
            {
375 e06e1b7e Leszek Koltunski
            time = Long.parseLong(timeStr);
376
            subm = Integer.parseInt(submStr);
377
378 7ac0ee88 Leszek Koltunski
            if( subm>=0 && subm<=1 )
379 e06e1b7e Leszek Koltunski
              {
380 7ac0ee88 Leszek Koltunski
              mRecords  [object][level] = time;
381
              mSubmitted[object][level] = subm;
382 e06e1b7e Leszek Koltunski
              }
383
            else
384
              {
385 7ac0ee88 Leszek Koltunski
              errorStr += ("error1: subm="+subm+" obj: "+nameStr+" size: "+sizeStr+"\n");
386 25445dcf Leszek Koltunski
              thereWasError= true;
387 e06e1b7e Leszek Koltunski
              }
388
            }
389
          else
390
            {
391 25445dcf Leszek Koltunski
            errorStr += ("error2: object="+object+" obj: "+nameStr+" size: "+sizeStr+"\n");
392
            thereWasError = true;
393 4895fff6 Leszek Koltunski
            }
394 4c0cd600 Leszek Koltunski
          }
395 e06e1b7e Leszek Koltunski
        }
396 4895fff6 Leszek Koltunski
      }
397
398 e06e1b7e Leszek Koltunski
    mName           = preferences.getString("scores_name"  , "" );
399
    mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
400
    mNumPlays       = preferences.getInt("scores_numPlays", 0);
401
    mNumRuns        = preferences.getInt("scores_numRuns" , 0);
402
    mDeviceID       = preferences.getInt("scores_deviceid",-1);
403 59aee296 Leszek Koltunski
    mNumWins        = preferences.getInt("scores_review"  , 0);
404 e06e1b7e Leszek Koltunski
405
    if( mDeviceID==-1 ) mDeviceID = privateGetDeviceID();
406 25445dcf Leszek Koltunski
407
    if( thereWasError ) recordDBError(errorStr);
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412
  public void recordDBError(String message)
413
    {
414
    if( BuildConfig.DEBUG )
415
      {
416
      android.util.Log.e("scores", message);
417
      }
418
    else
419
      {
420
      Exception ex = new Exception(message);
421
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
422
      crashlytics.setCustomKey("scores" , message);
423
      crashlytics.recordException(ex);
424
      }
425 4895fff6 Leszek Koltunski
    }
426
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428
429 7ac0ee88 Leszek Koltunski
  public synchronized boolean setRecord(int object, int level, long timeTaken)
430 4895fff6 Leszek Koltunski
    {
431 7ac0ee88 Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && level>=1 && level<=MAX_LEVEL && mRecords[object][level-1]>timeTaken )
432 6570171b Leszek Koltunski
      {
433 7ac0ee88 Leszek Koltunski
      mRecords  [object][level-1] = timeTaken;
434
      mSubmitted[object][level-1] = 0;
435
      return true;
436 6570171b Leszek Koltunski
      }
437 4895fff6 Leszek Koltunski
438 e06e1b7e Leszek Koltunski
    return false;
439 4895fff6 Leszek Koltunski
    }
440 f0e87514 Leszek Koltunski
  }