File indexing completed on 2023-10-03 03:29:21
0001 /* 0002 SPDX-FileCopyrightText: 2001-2004 Nicolas Hadacek <hadacek@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #ifndef KEXTHIGHSCORE_H 0008 #define KEXTHIGHSCORE_H 0009 0010 #include "kexthighscore_item.h" 0011 0012 #include <libkdegames_export.h> 0013 0014 #include <QLoggingCategory> 0015 #include <QVector> 0016 #include <QUrl> 0017 0018 namespace KExtHighscore 0019 { 0020 0021 class Score; 0022 class Item; 0023 0024 class ManagerPrivate; 0025 extern ManagerPrivate *internal; 0026 0027 /** 0028 * Get the current game type. 0029 */ 0030 uint gameType(); 0031 0032 /** 0033 * Set the current game type. 0034 */ 0035 void setGameType(uint gameType); 0036 0037 /** 0038 * Configure the highscores. 0039 * @return true if the configuration has been modified and saved 0040 */ 0041 bool configure(QWidget *parent); 0042 0043 /** 0044 * Show the highscores lists. 0045 */ 0046 void show(QWidget *parent); 0047 0048 /** 0049 * Submit a score. See @ref Manager for usage example. 0050 * 0051 * @param score the players score 0052 * @param widget a widget used as parent for error message box. 0053 */ 0054 void submitScore(const Score &score, QWidget *widget); 0055 0056 /** 0057 * @return the last score in the local list of highscores. The worst possible 0058 * score if there are less items than the maximum number. 0059 */ 0060 Score lastScore(); 0061 0062 /** 0063 * @return the first score in the local list of highscores (the worst possible 0064 * score if there is no entry). 0065 */ 0066 Score firstScore(); 0067 0068 /** 0069 * This class manages highscores and players entries (several players can 0070 * share the same highscores list if the libkdegame library is built to 0071 * support a common highscores file; NOTE that to correctly implement such 0072 * feature we probably need a locking mechanism in @ref KHighscore). 0073 * 0074 * You need one instance of this class during the application lifetime; in 0075 * main() just insert 0076 * \code 0077 * KExtHighscore::Manager highscoresManager; 0078 * \endcode 0079 * with the needed arguments. Use the derived class if you need to 0080 * reimplement some of the default methods. 0081 * 0082 * This class has three functions: 0083 * <ul> 0084 * <li> Update the highscores list when new entries are submitted </li> 0085 * <li> Display the highscores list and the players list </li> 0086 * <li> Send query to an optional web server to support world-wide 0087 * highscores </li> 0088 * </ul> 0089 * 0090 * The highscores and the players lists contain several items described by 0091 * the @ref Item class. 0092 * 0093 * The highscores list contains by default: 0094 * <ul> 0095 * <li> the player name (automatically set from the config value)</li> 0096 * <li> the score value </li> 0097 * <li> the time and date of the highscore (automatically set) </li> 0098 * </ul> 0099 * You can replace the score item (for e.g. displaying it differently) with 0100 * setScoreItem or add an item with addScoreItem. 0101 * 0102 * The players list contains: 0103 * <ul> 0104 * <li> the player name (as defined by the user in the configuration 0105 * dialog) </li> 0106 * <li> the number of games played </li> 0107 * <li> the mean score </li> 0108 * <li> the best score </li> 0109 * <li> the best score time and date </li> 0110 * <li> the player comment (as defined by the user in the 0111 * configuration dialog) </li> 0112 * </ul> 0113 * You can replace the best score and the mean score items 0114 * by calling setPlayerItem. 0115 * 0116 * To submit a new score at game end, just construct a Score, set the 0117 * score data and then call submitScore(). 0118 * \code 0119 * KExtHighscore::Score score(KExtHighscore::Won); 0120 * score.setScore(myScore); 0121 * KExtHighscore::submitScore(score, widget); 0122 * \endcode 0123 * You only need to set the score value with Score::setScore() 0124 * and the value of the items that you have optionally added 0125 * with Score::setData() player name and date are set automatically. 0126 */ 0127 class Manager 0128 { 0129 public: 0130 /** 0131 * Constructor 0132 * 0133 * @param nbGameTypes the number of different game types (usually one). 0134 * For example KMines has easy, normal and expert levels. 0135 * @param maxNbEntries the maximum numbers of highscores entries (by game 0136 * types) 0137 */ 0138 explicit Manager(uint nbGameTypes = 1, uint maxNbEntries = 10); 0139 virtual ~Manager(); 0140 0141 /** 0142 * Set the world-wide highscores. 0143 * By default there is no world-wide highscores. 0144 * 0145 * Note: should be called at construction time. 0146 * 0147 * @param url the web server url 0148 * @param version the game version which is sent to the web server (it can 0149 * be useful for backward compatibility on the server side). 0150 */ 0151 void setWWHighscores(const QUrl &url, const QString &version); 0152 0153 /** 0154 * Set if the number of lost games should be track for the world-wide 0155 * highscores statistics. By default, there is no tracking. 0156 * False by default. 0157 * 0158 * Note: should be called at construction time. 0159 */ 0160 void setTrackLostGames(bool track); 0161 0162 /** 0163 * Set if the number of "draw" games should be track for the world-wide 0164 * highscores statistics. By default, there is no tracking. 0165 * False by default. 0166 * 0167 * Note: should be called at construction time. 0168 */ 0169 void setTrackDrawGames(bool track); 0170 0171 /** 0172 * Set if the statistics tab should be shown in the highscores dialog. 0173 * You only want to show this tab if it makes sense to lose or to win the 0174 * game (for e.g. it makes no sense for a tetris game but it does for a 0175 * minesweeper game). 0176 * False by default. 0177 * 0178 * Note: should be called at construction time. 0179 */ 0180 void setShowStatistics(bool show); 0181 0182 /** 0183 * Set if draw games statistics should be shown (enable this if 0184 * draws are possible in your game). 0185 * False by default. 0186 */ 0187 void setShowDrawGamesStatistic(bool show); 0188 0189 enum ScoreTypeBound { ScoreNotBound, ScoreBound }; 0190 /** 0191 * Set the ranges for the score histogram. 0192 * 0193 * Note: should be called at construction time. 0194 */ 0195 void setScoreHistogram(const QVector<uint> &scores, ScoreTypeBound type); 0196 0197 /** 0198 * Enumerate different conditions under which to show the 0199 * high score dialog. 0200 */ 0201 enum ShowMode { AlwaysShow, ///< Always show the dialog 0202 NeverShow, ///< Never show the dialog 0203 ShowForHigherScore, ///< Show if score has improved 0204 ShowForHighestScore ///< Only for the top spot 0205 }; 0206 /** 0207 * Set how the highscores dialog is shown at game end. 0208 * By default, the mode is ShowForHigherScore. 0209 * 0210 * Note: should be called at construction time. 0211 */ 0212 void setShowMode(ShowMode mode); 0213 0214 /** 0215 * Score type (@see setScoreType). 0216 * @p Normal default score (unsigned integer without upper bound) 0217 * @p MinuteTime score by time bound at 3599 seconds (for e.g. kmines) 0218 */ 0219 enum ScoreType { Normal, MinuteTime }; 0220 /** 0221 * Set score type. Helper method to quickly set the type of score. 0222 * By default the type is Normal. 0223 * 0224 * Note: should be called at construction time. 0225 */ 0226 void setScoreType(ScoreType type); 0227 0228 /** 0229 * Some predefined item types. 0230 * @p ScoreDefault default item for the score in the highscores list. 0231 * @p MeanScoreDefault default item for the mean score (only show one decimal and 0232 * 0 is shown as "--". 0233 * @p BestScoreDefault default item for the best score (0 is shown as "--"). 0234 * @p ElapsedTime optional item for elapsed time (maximum value is 3599 seconds). 0235 */ 0236 enum ItemType { ScoreDefault, MeanScoreDefault, BestScoreDefault, 0237 ElapsedTime }; 0238 /** 0239 * Create a predefined item. 0240 */ 0241 static Item *createItem(ItemType type); 0242 0243 /** 0244 * Replace the default score item in the highscores list by the given one. 0245 * @p worstScore is the worst possible score. By default it is 0. 0246 * 0247 * Note: This method should be called at construction time. 0248 */ 0249 void setScoreItem(uint worstScore, Item *item); 0250 0251 /** 0252 * Add an item in the highscores list (it will add a column to this list). 0253 * 0254 * Note: This method should be called at construction time. 0255 */ 0256 void addScoreItem(const QString &name, Item *item); 0257 0258 enum PlayerItemType { MeanScore, BestScore }; 0259 /** 0260 * Replace an item in the players list. 0261 * 0262 * Note: This method should be called at construction time. 0263 */ 0264 void setPlayerItem(PlayerItemType type, Item *item); 0265 0266 /** 0267 * @return true if the first score is strictly worse than the second one. 0268 * By default return <pre>s1.score()<s2.score()</pre>. You can reimplement 0269 * this method if additional items added to @ref Score can further 0270 * differentiate the scores (for e.g. the time spent). 0271 * 0272 * Note that you do not need to use directly this method, simply write 0273 * <pre>s1<s2</pre> since the operator calls this method. 0274 */ 0275 virtual bool isStrictlyLess(const Score &s1, const Score &s2) const; 0276 0277 /** 0278 * Possible type of label (@see gameTypeLabel). 0279 * @p Standard label used in config file. 0280 * @p I18N label used to display the game type. 0281 * @p WW label used when contacting the world-wide highscores server. 0282 * @p Icon label used to load the icon corresponding to the game type. 0283 */ 0284 enum LabelType { Standard, I18N, WW, Icon }; 0285 0286 /** 0287 * @return the label corresponding to the game type. The default 0288 * implementation works only for one game type: you need to reimplement 0289 * this method if the number of game types is more than one. 0290 */ 0291 virtual QString gameTypeLabel(uint gameType, LabelType type) const; 0292 0293 protected: 0294 /** 0295 * This method is called once for each player (ie for each user). You 0296 * can reimplement it to convert old style highscores to the new mechanism 0297 * (@see submitLegacyScore). By default this method does nothing. 0298 * 0299 * @param gameType the game type 0300 */ 0301 virtual void convertLegacy(uint gameType) { Q_UNUSED(gameType); } 0302 0303 /** 0304 * This method should be called from @ref convertLegacy. It is used 0305 * to submit an old highscore (it will not be sent over the network). 0306 * For each score do something like: 0307 * \code 0308 * Score score(Won); 0309 * score.setScore(oldScore); 0310 * score.setData("name", name); 0311 * submitLegacyScore(score); 0312 * \endcode 0313 * Note that here you can set the player "name" and the highscore "date" 0314 * if they are known. 0315 */ 0316 void submitLegacyScore(const Score &score) const; 0317 0318 /** 0319 * This method is called before submitting a score to the world-wide 0320 * highscores server. You can reimplement this method to add an entry 0321 * with @ref addToQueryURL. By default this method does nothing. 0322 * 0323 * @param url the URL to query 0324 * @param score the score to be submitted. 0325 */ 0326 virtual void additionalQueryItems(QUrl &url, const Score &score) const 0327 { Q_UNUSED(url); Q_UNUSED(score); } 0328 0329 /** 0330 * Add an entry to the url to be submitted (@see additionalQueryItems). 0331 * 0332 * @param url the URL to query 0333 * @param item the item name 0334 * @param content the item content 0335 */ 0336 static void addToQueryURL(QUrl &url, const QString &item, 0337 const QString &content); 0338 0339 friend class ManagerPrivate; 0340 0341 private: 0342 Manager(const Manager &); 0343 Manager &operator =(const Manager &); 0344 }; 0345 0346 } // namespace 0347 0348 Q_DECLARE_LOGGING_CATEGORY(GAMES_EXTHIGHSCORE) 0349 0350 #endif