|
|
|
/*
|
|
|
|
This file is part of the KDE games library
|
|
|
|
Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
|
|
|
|
Copyright (C) 2003 Nicolas Hadacek <hadacek@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
$Id$
|
|
|
|
*/
|
|
|
|
#ifndef __KHIGHSCORE_H__
|
|
|
|
#define __KHIGHSCORE_H__
|
|
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <kdemacros.h>
|
|
|
|
class KConfig;
|
|
|
|
class KFileLock;
|
|
|
|
class KRawConfig;
|
|
|
|
class KHighscorePrivate;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @short Class for managing highscore tables
|
|
|
|
*
|
|
|
|
* This is the KDE class for saving and reading highscore tables. It offers the
|
|
|
|
* possibility for system-wide highscore tables (configure with e.g.
|
|
|
|
* --enable-highscore-dir=/var/games) and a theoretically unlimited number of
|
|
|
|
* entries.
|
|
|
|
*
|
|
|
|
* You can specify different "keys" for an entry - just like the KConfig
|
|
|
|
* keys. But it will be prefixed with the number of the entry. For example you
|
|
|
|
* will probably use something like this to save the name of the player on the
|
|
|
|
* top of the list (ie the winner):
|
|
|
|
* \code
|
|
|
|
* highscore->writeEntry(1, "name", myPlayer->name());
|
|
|
|
* \endcode
|
|
|
|
* Note that it doesn't really matter if you use "0" or "1" as the first entry
|
|
|
|
* of the list as long as your program always uses the same for the first
|
|
|
|
* entry. I recommend to use "1", as several convenience methods use this.
|
|
|
|
*
|
|
|
|
* You can also specify different groups using setHighscoreGroup. Just
|
|
|
|
* like the keys mentioned above the groups behave like groups in KConfig
|
|
|
|
* but are prefixed with "KHighscore_". The default group is just "KHighscore".
|
|
|
|
* You might use this e.g. to create different highscore tables like
|
|
|
|
* \code
|
|
|
|
* table->setHighscoreGroup("Easy");
|
|
|
|
* // write the highscores for level "easy" to the table
|
|
|
|
* writeEasyHighscores(table);
|
|
|
|
*
|
|
|
|
* table->setHighscore("Player_1");
|
|
|
|
* // write player specific highscores to the table
|
|
|
|
* writePlayerHighscores(table);
|
|
|
|
* \endcode
|
|
|
|
* As you can see above you can also use this to write the highscores of a
|
|
|
|
* single player, so the "best times" of a player. To write highscores for a
|
|
|
|
* specific player in a specific level you will have to use a more complex way:
|
|
|
|
* \code
|
|
|
|
* TQString group = TQString("%1_%2").tqarg(player).tqarg(level);
|
|
|
|
* table->setGroup(group);
|
|
|
|
* writeHighscore(table, player, level);
|
|
|
|
* \endcode
|
|
|
|
*
|
|
|
|
* Also note that you MUST NOT mark the key or the group for translation! I.e.
|
|
|
|
* don't use i18n() for the keys or groups! Here is the code to read the above
|
|
|
|
* written entry:
|
|
|
|
* \code
|
|
|
|
* TQString firstName = highscore->readEntry(0, "name");
|
|
|
|
* \endcode
|
|
|
|
* Easy, what?
|
|
|
|
* @author Andreas Beckermann <b_mann@gmx.de>
|
|
|
|
**/
|
|
|
|
class KDE_EXPORT KHighscore : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
TQ_OBJECT
|
|
|
|
public:
|
|
|
|
/** @obsolete
|
|
|
|
* Constructor. The highscore file is forced to be local to support
|
|
|
|
* games using the old behaviour.
|
|
|
|
*/
|
|
|
|
KHighscore(TQObject* tqparent = 0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param forceLocal if true, the local highscore file is used even
|
|
|
|
* when the configuration has been set to use a system-wide file. This
|
|
|
|
* is convenient for converting highscores from legacy applications.
|
|
|
|
* @param tqparent tqparent widget for this widget
|
|
|
|
* @since 3.2
|
|
|
|
*/
|
|
|
|
KHighscore(bool forceLocal, TQObject *tqparent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read the current state of the highscore file. Remember that when
|
|
|
|
* it's not locked for writing, this file can change at any time.
|
|
|
|
* (This method is only useful for a system-wide highscore file).
|
|
|
|
* @since 3.2
|
|
|
|
*/
|
|
|
|
void readCurrentConfig();
|
|
|
|
|
|
|
|
/** @since 3.2
|
|
|
|
* This method open the system-wide highscore file using the effective
|
|
|
|
* group id of the game executable (which should be "games"). The
|
|
|
|
* effective group id is completely dropped afterwards.
|
|
|
|
*
|
|
|
|
* Note: this method should be called in main() before creating a
|
|
|
|
* KApplication and doing anything else (KApplication checks that the
|
|
|
|
* program is not suid/sgid and will exit the program for security
|
|
|
|
* reason if it is the case).
|
|
|
|
*/
|
|
|
|
static void init(const char *appname);
|
|
|
|
|
|
|
|
/** @since 3.2
|
|
|
|
* Lock the system-wide highscore file for writing (does nothing and
|
|
|
|
* return true if the local file is used).
|
|
|
|
* You should perform writing without GUI interaction to avoid
|
|
|
|
* blocking and don't forget to unlock the file as soon as possible
|
|
|
|
* with writeAndUnlock().
|
|
|
|
*
|
|
|
|
* If the config file cannot be locked,
|
|
|
|
* the method waits for 1 second and, if it failed again, displays
|
|
|
|
* a message box asking for retry or cancel.
|
|
|
|
* @param widget used as the tqparent of the message box.
|
|
|
|
*
|
|
|
|
* @return false on error or if the config file is locked by another
|
|
|
|
* process. In such case, the config stays read-only.
|
|
|
|
*/
|
|
|
|
bool lockForWriting(TQWidget *widget = 0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Effectively write and unlock the system-wide highscore file
|
|
|
|
* (@see lockForWriting).
|
|
|
|
* If using a local highscore file, it will sync the config.
|
|
|
|
* @since 3.2
|
|
|
|
*/
|
|
|
|
void writeAndUnlock();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the highscore file is locked or if a local
|
|
|
|
* file is used.
|
|
|
|
* @since 3.2
|
|
|
|
*/
|
|
|
|
bool isLocked() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor.
|
|
|
|
* If necessary, write and unlock the highscore file.
|
|
|
|
*/
|
|
|
|
~KHighscore();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param entry The number of the entry / the placing of the player
|
|
|
|
* @param key A key for this entry. E.g. "name" for the name of the
|
|
|
|
* player. Nearly the same as the usual keys in KConfig - but they
|
|
|
|
* are prefixed with the entry number
|
|
|
|
* @param value The value of this entry
|
|
|
|
**/
|
|
|
|
void writeEntry(int entry, const TQString& key, const TQString& value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an overloaded member function, provided for convenience.
|
|
|
|
* It differs from the above function only in what argument(s) it accepts.
|
|
|
|
**/
|
|
|
|
void writeEntry(int entry, const TQString& key, int value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an overloaded member function, provided for convenience.
|
|
|
|
* It differs from the above function only in what argument(s) it accepts.
|
|
|
|
* See KConfigBase documentation for allowed TQVariant::Type.
|
|
|
|
**/
|
|
|
|
void writeEntry(int entry, const TQString& key, const TQVariant &value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads an entry from the highscore table.
|
|
|
|
* @param entry The number of the entry / the placing to be read
|
|
|
|
* @param key The key of the entry. E.g. "name" for the name of the
|
|
|
|
* player. Nearly the same as the usual keys in KConfig - but they
|
|
|
|
* are prefixed with the entry number
|
|
|
|
* @param pDefault This will be used as default value if the key+pair
|
|
|
|
* entry can't be found.
|
|
|
|
* @return The value of this entry+key pair or pDefault if the entry+key
|
|
|
|
* pair doesn't exist
|
|
|
|
**/
|
|
|
|
TQString readEntry(int entry, const TQString& key, const TQString& pDefault = TQString()) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read a numeric value.
|
|
|
|
* @param entry The number of the entry / the placing to be read
|
|
|
|
* @param key The key of the entry. E.g. "name" for the name of the
|
|
|
|
* player. Nearly the same as the usual keys in KConfig - but they
|
|
|
|
* are prefixed with the entry number
|
|
|
|
* @param pDefault This will be used as default value if the key+pair
|
|
|
|
* entry can't be found.
|
|
|
|
* @return The value of this entry+key pair or pDefault if the entry+key
|
|
|
|
* pair doesn't exist
|
|
|
|
**/
|
|
|
|
int readNumEntry(int entry, const TQString& key, int pDefault = -1) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read a TQVariant entry.
|
|
|
|
* See KConfigBase documentation for allowed TQVariant::Type.
|
|
|
|
*
|
|
|
|
* @return the value of this entry+key pair or pDefault if the entry+key
|
|
|
|
* pair doesn't exist or
|
|
|
|
*/
|
|
|
|
TQVariant readPropertyEntry(int entry, const TQString &key, const TQVariant &pDefault) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return True if the highscore table conatins the entry/key pair,
|
|
|
|
* otherwise false
|
|
|
|
**/
|
|
|
|
bool hasEntry(int entry, const TQString& key) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads a list of entries from the highscore table starting at 1 until
|
|
|
|
* lastEntry. If an entry between those numbers doesn't exist the
|
|
|
|
* function aborts reading even if after the missing entry is an
|
|
|
|
* existing one. The first entry of the list is the first placing, the
|
|
|
|
* last on is the last placing.
|
|
|
|
* @return A list of the entries of this key. You could also call
|
|
|
|
* readEntry(i, key) where i is from 1 to 20. Note that this function
|
|
|
|
* depends on "1" as the first entry!
|
|
|
|
* @param key The key of the entry. E.g. "name" for the name of the
|
|
|
|
* player. Nearly the same as the usual keys in KConfig - but they
|
|
|
|
* are prefixed with the entry number
|
|
|
|
* @param lastEntry the last entry which will be includes into the list.
|
|
|
|
* 1 will include a list with maximal 1 entry - 20 a list with maximal
|
|
|
|
* 20 entries. If lastEntry is <= 0 then rading is only stopped when when an
|
|
|
|
* entry does not exist.
|
|
|
|
**/
|
|
|
|
TQStringList readList(const TQString& key, int lastEntry = 20) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes a list of entries to the highscore table.
|
|
|
|
*
|
|
|
|
* The first entry is prefixed with "1". Using this method is a short
|
|
|
|
* way of calling writeEntry(i, key, list[i]) from i = 1 to
|
|
|
|
* list.count()
|
|
|
|
* @param key A key for the entry. E.g. "name" for the name of the
|
|
|
|
* player. Nearly the same as the usual keys in KConfig - but they
|
|
|
|
* are prefixed with the entry number
|
|
|
|
* @param list The list of values
|
|
|
|
**/
|
|
|
|
void writeList(const TQString& key, const TQStringList& list);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Whether a highscore table exists. You can use this
|
|
|
|
* function to indicate whether KHighscore created a highscore table
|
|
|
|
* before and - if not - read your old (non-KHighscore) table instead.
|
|
|
|
* This way you can safely read an old table and save it using
|
|
|
|
* KHighscore without losing any data
|
|
|
|
**/
|
|
|
|
bool hasTable() const;
|
|
|
|
|
|
|
|
/** @obsolete
|
|
|
|
* This does the same as writeAndUnlock().
|
|
|
|
*/
|
|
|
|
void sync();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the new highscore group. The group is being prefixed with
|
|
|
|
* "KHighscore_" in the table.
|
|
|
|
* @param groupname The new groupname. E.g. use "easy" for the easy
|
|
|
|
* level of your game. If you use TQString() (the default) the
|
|
|
|
* default group is used.
|
|
|
|
**/
|
|
|
|
void setHighscoreGroup(const TQString& groupname = TQString());
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return The currently used group. This doesn't contain the prefix
|
|
|
|
* ("KHighscore_") but the same as setHighscoreGroup uses. The
|
|
|
|
* default is TQString()
|
|
|
|
**/
|
|
|
|
const TQString& highscoreGroup() const;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
* @return A groupname to be used in KConfig. Used internally to
|
|
|
|
* prefix the value from highscoreGroup() with "KHighscore_"
|
|
|
|
**/
|
|
|
|
TQString group() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return A pointer to the KConfig object to be used. This is
|
|
|
|
* either kapp->config() (default) or a KSimpleConfig object for
|
|
|
|
* a system-wide highscore file.
|
|
|
|
**/
|
|
|
|
KConfig* config() const;
|
|
|
|
|
|
|
|
void init(bool forceLocal);
|
|
|
|
|
|
|
|
private:
|
|
|
|
KHighscorePrivate* d;
|
|
|
|
|
|
|
|
static KFileLock *_lock; // lock on system-wide highscore file
|
|
|
|
static KRawConfig *_config; // config for system-wide highscore file
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|