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
34ScoreFile::ScoreFile(const wxString& appName)
35{
36    m_config = new wxConfig(appName, _T("wxWidgets"), appName, wxEmptyString,
37                                wxCONFIG_USE_LOCAL_FILE);  // only local
38}
39
40ScoreFile::~ScoreFile()
41{
42    delete m_config;
43}
44
45
46void 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
68long 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
87wxString 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
95void 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
129void 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