diff --git a/DB_Changes.txt b/DB_Changes.txt index 4447238..79191a8 100644 --- a/DB_Changes.txt +++ b/DB_Changes.txt @@ -24,6 +24,12 @@ updates -> Removed col 'Log' ms4_log -> Added +entrys -> ms4_highscoreentries +games -> ms4_highscoregames +ms4_highscoreentries.IP -> length = 41 + + + updateslog -> new table db->createCommand('SELECT * FROM {{updates}}')->queryAll(); diff --git a/www/protected/config/main.php b/www/protected/config/main.php index 37f6a77..bd9c00e 100644 --- a/www/protected/config/main.php +++ b/www/protected/config/main.php @@ -91,6 +91,12 @@ return ArrayX::merge( 'blog/' => 'blogPost/view/id/', 'blog//' => 'blogPost/view/id/', + 'Highscores/list.php' => 'Highscores/list', // Compatibility + 'Highscores/insert.php' => 'Highscores/insert', // Compatibility + 'Highscores/update.php' => 'Highscores/update', // Compatibility + 'Highscores/list_top50.php' => 'Highscores/list_top50', // Compatibility + 'Highscores/getNewID.php' => 'Highscores/newID', // Compatibility + 'downloads/details.php' => 'programs/index', // Compatibility 'downloads/downloads.php' => 'programs/index', // Compatibility 'downloads/' => 'programs/view', // Compatibility diff --git a/www/protected/controllers/APIController.php b/www/protected/controllers/APIController.php index 72e4568..cef6c40 100644 --- a/www/protected/controllers/APIController.php +++ b/www/protected/controllers/APIController.php @@ -51,4 +51,9 @@ class APIController extends MSController $this->render('update', ['data' => $data]); } + + public function actionTest() + { + $this->render('test', []); + } } \ No newline at end of file diff --git a/www/protected/controllers/HighscoresController.php b/www/protected/controllers/HighscoresController.php new file mode 100644 index 0000000..186d5f4 --- /dev/null +++ b/www/protected/controllers/HighscoresController.php @@ -0,0 +1,222 @@ +array('*'), + ), + ); + } + + public function actionInsert($gameid, $check, $name, $rand, $points) + { + if (! is_numeric($gameid)) + throw new CHttpException(400, 'Invalid Request'); + if (! is_numeric($points)) + throw new CHttpException(400, 'Invalid Request'); + + $entry = new HighscoreEntries(); + $entry->GAME_ID = $gameid; + $entry->POINTS = $points; + $entry->PLAYER = $name; + $entry->PLAYERID = -1; + $entry->CHECKSUM = $check; + $entry->TIMESTAMP = time(); + $entry->IP = $_SERVER['REMOTE_ADDR']; + + if ($entry->checkChecksum($rand)) + { + if ($entry->save()) + { + $this->actionListEntries($gameid); + return; + } + else + { + echo 'Error while inserting'; + return; + } + } + else + { + echo 'Nice try !'; + return; + } + } + + public function actionList() + { + if (!isset($_GET["gameid"])) + { + $this->actionListGames(); + return; + } + else + { + $this->actionListEntries(intval(mysql_real_escape_string($_GET["gameid"]))); + return; + } + } + + public function actionListEntries($gameid) + { + if (! is_numeric($gameid)) + throw new CHttpException(400, 'Invalid Request - [gameid] must be an integer'); + + if (!isset($_GET["start"])) + { + $start = 0; + } + else + { + $start = intval(mysql_real_escape_string($_GET["start"])) - 1; + if ($start < 0) + { + $start = 0; + } + } + + if (isset($_GET["highlight"])) + { + $highlight= intval(mysql_real_escape_string($_GET["highlight"])); + } + else + $highlight = 0; + + $game = HighscoreGames::model()->findByPk($gameid); + + $this->render('listentries', + [ + 'game' => $game, + 'start' => $start, + 'highlight' => $highlight, + 'pagesize' => self::ENTRYLIST_PAGESIZE, + ]); + } + + public function actionListGames() + { + $criteria = new CDbCriteria; + $games = HighscoreGames::model()->findAll($criteria); + + $this->render('listgames', + [ + 'games' => $games, + ]); + } + + public function actionUpdate($gameid, $check, $name, $nameid, $rand, $points) + { + if (! is_numeric($gameid)) + throw new CHttpException(400, 'Invalid Request'); + if (! is_numeric($nameid)) + throw new CHttpException(400, 'Invalid Request'); + if (! is_numeric($points)) + throw new CHttpException(400, 'Invalid Request'); + + $criteria = new CDbCriteria; + $criteria->addCondition('GAME_ID = ' . $gameid); + $criteria->addCondition('PLAYERID = ' . $nameid); + + /* @var HighscoreEntries $entry */ + $entry = HighscoreEntries::model()->find($criteria); + + if (is_null($entry)) + { + $entry = new HighscoreEntries(); + $entry->GAME_ID = $gameid; + $entry->POINTS = $points; + $entry->PLAYER = $name; + $entry->PLAYERID = -1; + $entry->CHECKSUM = $check; + $entry->TIMESTAMP = time(); + $entry->IP = $_SERVER['REMOTE_ADDR']; + + if ($entry->checkChecksum($rand)) + { + if ($entry->save()) + { + $this->actionListEntries($gameid); + return; + } + else + { + echo 'Error while inserting'; + return; + } + } + else + { + echo 'Nice try !'; + return; + } + } + else + { + $entry->POINTS = $points; + $entry->PLAYER = $name; + $entry->CHECKSUM = $check; + $entry->IP = $_SERVER['REMOTE_ADDR']; + + if ($entry->checkChecksum($rand)) + { + $entry->update(); + $this->actionListEntries($gameid); + } + else + { + echo 'Nice try !'; + return; + } + } + + } + + public function actionList_Top50($gameid) + { + if (! is_numeric($gameid)) + throw new CHttpException(400, 'Invalid Request - [gameid] must be an integer'); + + $game = HighscoreGames::model()->findByPk($gameid); + + $this->render('list_top50', + [ + 'game' => $game, + ]); + } + + public function actionNewID($gameid) + { + $connection=Yii::app()->db; + $command=$connection->createCommand("SELECT MAX(PLAYERID)+1 AS NID FROM {{highscoreentries}} WHERE GAME_ID = $gameid"); + + $newid = $command->queryScalar(); + if ($newid < 1024) { + $newid = 1024; + } + + print $newid; + } +} \ No newline at end of file diff --git a/www/protected/models/HighscoreEntries.php b/www/protected/models/HighscoreEntries.php new file mode 100644 index 0000000..b39424f --- /dev/null +++ b/www/protected/models/HighscoreEntries.php @@ -0,0 +1,149 @@ +true), + array('POINTS', 'length', 'max'=>20), + array('PLAYER, IP', 'length', 'max'=>41), + array('CHECKSUM', 'length', 'max'=>32), + // The following rule is used by search(). + // @todo Please remove those attributes that should not be searched. + array('GAME_ID, POINTS, PLAYER, PLAYERID, CHECKSUM, TIMESTAMP, IP', 'safe', 'on'=>'search'), + ); + } + + /** + * @return array relational rules. + */ + public function relations() + { + // NOTE: you may need to adjust the relation name and the related + // class name for the relations automatically generated below. + return array( + 'GAME' => + [ + self::HAS_ONE, + 'HighscoreGames', + [ + 'ID' => 'GAME_ID' + ] + ], + ); + } + + /** + * @return array customized attribute labels (name=>label) + */ + public function attributeLabels() + { + return array( + 'GAME_ID' => 'Game', + 'POINTS' => 'Points', + 'PLAYER' => 'Player', + 'PLAYERID' => 'Playerid', + 'CHECKSUM' => 'Checksum', + 'TIMESTAMP' => 'Timestamp', + 'IP' => 'IP', + ); + } + + /** + * Retrieves a list of models based on the current search/filter conditions. + * + * Typical usecase: + * - Initialize the model fields with values from filter form. + * - Execute this method to get CActiveDataProvider instance which will filter + * models according to data in model fields. + * - Pass data provider to CGridView, CListView or any similar widget. + * + * @return CActiveDataProvider the data provider that can return the models + * based on the search/filter conditions. + */ + public function search() + { + // @todo Please modify the following code to remove attributes that should not be searched. + + $criteria=new CDbCriteria; + + $criteria->compare('GAME_ID',$this->GAME_ID); + $criteria->compare('POINTS',$this->POINTS,true); + $criteria->compare('PLAYER',$this->PLAYER,true); + $criteria->compare('PLAYERID',$this->PLAYERID); + $criteria->compare('CHECKSUM',$this->CHECKSUM,true); + $criteria->compare('TIMESTAMP',$this->TIMESTAMP,true); + $criteria->compare('IP',$this->IP,true); + + return new CActiveDataProvider($this, array( + 'criteria'=>$criteria, + )); + } + + /** + * Returns the static model of the specified AR class. + * Please note that you should have this exact method in all your CActiveRecord descendants! + * @param string $className active record class name. + * @return HighscoreEntries the static model class + */ + public static function model($className=__CLASS__) + { + return parent::model($className); + } + + //#################################### + //########### MY FUNCTIONS ########### + //#################################### + + /** + * @param $rand + * @return string + */ + public function generateChecksum($rand) + { + $game = HighscoreGames::model()->findByPk($this->GAME_ID); + /* @var $game HighscoreGames */ + + if ($this->PLAYERID >= 0) + return md5($rand . $this->PLAYER . $this->PLAYERID . $this->POINTS . $game->ID); + else + return md5($rand . $this->PLAYER . $this->POINTS . $game->ID); + } + + /** + * @param $rand + * @return bool + */ + public function checkChecksum($rand) + { + return $this->generateChecksum($rand) == $this->CHECKSUM; + } +} diff --git a/www/protected/models/HighscoreGames.php b/www/protected/models/HighscoreGames.php new file mode 100644 index 0000000..59e5961 --- /dev/null +++ b/www/protected/models/HighscoreGames.php @@ -0,0 +1,118 @@ +63), + array('SALT', 'length', 'max'=>6), + // The following rule is used by search(). + array('ID, NAME', 'safe', 'on'=>'search'), + ); + } + + /** + * @return array relational rules. + */ + public function relations() + { + // NOTE: you may need to adjust the relation name and the related + // class name for the relations automatically generated below. + return array( + 'ENTRIES' => + [ + self::HAS_MANY, + 'HighscoreEntries', + [ + 'GAME_ID' => 'ID' + ], + 'order'=>'POINTS DESC' + ], + ); + } + + /** + * @return array customized attribute labels (name=>label) + */ + public function attributeLabels() + { + return array( + 'ID' => 'ID', + 'NAME' => 'Name', + 'SALT' => 'Salt', + ); + } + + /** + * Retrieves a list of models based on the current search/filter conditions. + * + * Typical usecase: + * - Initialize the model fields with values from filter form. + * - Execute this method to get CActiveDataProvider instance which will filter + * models according to data in model fields. + * - Pass data provider to CGridView, CListView or any similar widget. + * + * @return CActiveDataProvider the data provider that can return the models + * based on the search/filter conditions. + */ + public function search() + { + // @todo Please modify the following code to remove attributes that should not be searched. + + $criteria=new CDbCriteria; + + $criteria->compare('ID',$this->ID); + $criteria->compare('NAME',$this->NAME,true); + + return new CActiveDataProvider($this, array( + 'criteria'=>$criteria, + )); + } + + /** + * Returns the static model of the specified AR class. + * Please note that you should have this exact method in all your CActiveRecord descendants! + * @param string $className active record class name. + * @return HighscoreGames the static model class + */ + public static function model($className=__CLASS__) + { + return parent::model($className); + } + + //#################################### + //########### MY FUNCTIONS ########### + //#################################### + + /** + * @return string + */ + public function getListLink() + { + return '/Highscores/list?gameid=' . $this->ID; + } +} diff --git a/www/protected/models/ProgramUpdates.php b/www/protected/models/ProgramUpdates.php index 36f035b..d030877 100644 --- a/www/protected/models/ProgramUpdates.php +++ b/www/protected/models/ProgramUpdates.php @@ -49,7 +49,8 @@ class ProgramUpdates extends CActiveRecord 'ProgramUpdatesLog', [ 'programname' => 'Name' - ]], + ] + ], ); } diff --git a/www/protected/views/Highscores/list_top50.php b/www/protected/views/Highscores/list_top50.php new file mode 100644 index 0000000..1b1b17f --- /dev/null +++ b/www/protected/views/Highscores/list_top50.php @@ -0,0 +1,8 @@ +ENTRIES[$i]->POINTS . '||' . htmlentities($game->ENTRIES[$i]->PLAYER) . "\r\n"); +} \ No newline at end of file diff --git a/www/protected/views/Highscores/listentries.php b/www/protected/views/Highscores/listentries.php new file mode 100644 index 0000000..f9f18c9 --- /dev/null +++ b/www/protected/views/Highscores/listentries.php @@ -0,0 +1,102 @@ + + + + + + + highscores + + + + + + + + + + + + + ENTRIES as $entry) + { + $current++; + + if ($current >= $start && $current - $start <= $pagesize) + { + if ($current == $highlight) + echo ''; + else + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + } + + $more = max(0, $start - $pagesize); + $less = $start + $pagesize; + + echo ''; + if ($start > 0) + echo ''; + else + echo ''; + echo ''; + if ($start + $pagesize < count($game->ENTRIES)) + echo ''; + else + echo ''; + echo ''; + + ?> +
NAME; ?>
rankpointsname
$current$entry->POINTS$entry->PLAYER
ID&start=$more&highlight=$highlight" . '">[more points]ID&start=$less&highlight=$highlight" . '">[less points]
+ + \ No newline at end of file diff --git a/www/protected/views/Highscores/listgames.php b/www/protected/views/Highscores/listgames.php new file mode 100644 index 0000000..4813dfc --- /dev/null +++ b/www/protected/views/Highscores/listgames.php @@ -0,0 +1,36 @@ + + + + + + highscores + + + + +getListLink() . '">' . $game->NAME . '
' . "\r\n"; + } +?> + + + \ No newline at end of file diff --git a/www/protected/views/api/test.php b/www/protected/views/api/test.php new file mode 100644 index 0000000..73e29fa --- /dev/null +++ b/www/protected/views/api/test.php @@ -0,0 +1,7 @@ +findByPk(1); + +echo nl2br(print_r( $gm->ENTRIES, true));