1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        scorefil.cpp
3 // Purpose:     Forty Thieves patience game
4 // Author:      Chris Breeze
5 // Modified by:
6 // Created:     21/07/97
7 // RCS-ID:      $Id: scorefil.cpp 43990 2006-12-16 15:18:41Z VZ $
8 // Copyright:   (c) 1993-1998 Chris Breeze
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14 
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18 
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22 
23 #ifdef __WXGTK__
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #endif
28 #include "wx/textfile.h"
29 #include "wx/config.h"
30 #include "wx/fileconf.h"
31 
32 #include "scorefil.h"
33 
ScoreFile(const wxString & appName)34 ScoreFile::ScoreFile(const wxString& appName)
35 {
36     m_config = new wxConfig(appName, _T("wxWidgets"), appName, wxEmptyString,
37                                 wxCONFIG_USE_LOCAL_FILE);  // only local
38 }
39 
~ScoreFile()40 ScoreFile::~ScoreFile()
41 {
42     delete m_config;
43 }
44 
45 
GetPlayerList(wxArrayString & list)46 void ScoreFile::GetPlayerList( wxArrayString &list )
47 {
48     m_config->SetPath(_T("/Players"));
49     int length = m_config->GetNumberOfGroups();
50 
51     if (length <= 0) return;
52 
53     wxString player;
54     long index;
55     if (m_config->GetFirstGroup(player, index))
56     {
57          list.Add( player );
58         while (m_config->GetNextGroup(player, index))
59         {
60               list.Add( player );
61         }
62     }
63 }
64 
65 
66 // Calculate an encrypted check number to prevent tampering with
67 // score file
CalcCheck(const wxString & name,int p1,int p2,int p3)68 long ScoreFile::CalcCheck(const wxString& name, int p1, int p2, int p3)
69 {
70     long check = 0;
71     size_t i, max = name.length();
72 
73     for(i = 0; i < max; ++i )
74     {
75         check = (check << 1) ^ (long)name[i];
76         check = ((check >> 23) ^ check) & 0xFFFFFF;
77     }
78     check = (check << 1) ^ (long)p1;
79     check = ((check >> 23) ^ check) & 0xFFFFFF;
80     check = (check << 1) ^ (long)p2;
81     check = ((check >> 23) ^ check) & 0xFFFFFF;
82     check = (check << 1) ^ (long)p3;
83     check = ((check >> 23) ^ check) & 0xFFFFFF;
84     return check;
85 }
86 
GetPreviousPlayer() const87 wxString ScoreFile::GetPreviousPlayer() const
88 {
89     wxString result;
90     m_config->SetPath(_T("/General"));
91     m_config->Read(_T("LastPlayer"), &result);
92     return result;
93 }
94 
ReadPlayersScore(const wxString & player,int & wins,int & games,int & score)95 void ScoreFile::ReadPlayersScore(
96                         const wxString& player,
97                         int& wins,
98                         int& games,
99                         int& score)
100 {
101     long check = 0;
102     long myWins = 0, myGames = 0, myScore = 0;
103 
104     games = wins = score = 0;
105 
106     m_config->SetPath(_T("/Players"));
107     m_config->SetPath(player);
108     if (m_config->Read(_T("Score"), &myScore, 0L) &&
109         m_config->Read(_T("Games"), &myGames, 0L) &&
110         m_config->Read(_T("Wins"),  &myWins, 0L) &&
111         m_config->Read(_T("Check"), &check, 0L))
112     {
113         if (check != CalcCheck(player, myGames, myWins, myScore))
114         {
115             wxMessageBox(_T("Score file corrupted"), _T("Warning"),
116                                      wxOK | wxICON_EXCLAMATION);
117         }
118         else
119         {
120             games = myGames;
121             wins = myWins;
122             score = myScore;
123         }
124     }
125     WritePlayersScore(player, wins, games, score);
126 }
127 
128 
WritePlayersScore(const wxString & player,int wins,int games,int score)129 void ScoreFile::WritePlayersScore(const wxString& player, int wins, int games, int score)
130 {
131     if (player)
132     {
133         m_config->SetPath(_T("/General"));
134         m_config->Write(_T("LastPlayer"), wxString(player)); // Without wxString tmp, thinks it's bool in VC++
135 
136         m_config->SetPath(_T("/Players"));
137         m_config->SetPath(player);
138         m_config->Write(_T("Score"), (long)score);
139         m_config->Write(_T("Games"), (long)games);
140         m_config->Write(_T("Wins"), (long)wins);
141         m_config->Write(_T("Check"), CalcCheck(player, games, wins, score));
142     }
143 }
144