/[drupal]/contributions/modules/arcade/arcade.module
ViewVC logotype

Contents of /contributions/modules/arcade/arcade.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Thu Apr 9 07:22:34 2009 UTC (7 months, 2 weeks ago) by matt2000
Branch: MAIN
CVS Tags: DRUPAL-6--0-9-BETA1, HEAD
Changes since 1.2: +64 -17 lines
File MIME type: text/x-php
numerous fixes and code clean-up
1 <?php
2 // $Id: arcade.module,v 1.2 2009/04/09 02:49:44 matt2000 Exp $
3
4 /**
5 * @file Arcade
6 * Identify nodes as games and store Score info
7 */
8
9
10 //Many older pnFlashGames ignore the pn_script variable and post to index.php anyway. So we catch that and redirect here:
11 if (isset($_POST['game_protocol']) || (isset($_POST['module']) && $_POST['module'] == 'pnFlashGames')) {
12 include_once(drupal_get_path('module','arcade') ."/gameserver.php");
13 exit;
14 }
15
16 /**
17 * Implementation of hook_perm
18 */
19 function arcade_perm() {
20 return array('view high scores');
21 }
22
23
24 /**
25 * Implementation of hook_nodeapi().
26 */
27 function arcade_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
28
29 if (!variable_get('is_game_'. $node->type, 0)) return; // we only work on nodes of types that might be games
30
31 switch ($op) {
32
33 case 'load':
34 // The node is about to be loaded from the database. This hook can be used
35 // to load additional data at this time.
36
37 //get game data
38 $game_data = db_fetch_object(db_query("SELECT * FROM {arcade_games} WHERE nid = %d", $node->nid));
39 if (!empty($game_data)) {
40 $node->is_game = 1;
41 $node->game_type = $game_data->game_type;
42 $node->game_path = $game_data->game_path;
43 $node->arcade_secure = $game_data->secure;
44
45 if ($node->type == 'flashnode') {
46 $node->flashnode['orig_vars'] = $node->flashnode['flashvars'];
47 global $user;
48 $host = arcade_getDomain();
49 if (!empty($node->flashnode['flashvars'])) { $node->flashnode['flashvars'] .= "&"; }
50 if ($node->arcade_secure) {
51 $checksum = arcade_get_checksum($node->flashnode['filepath']);
52 $key = md5($checksum . time());
53 $token = variable_get('arcade_token', FALSE);
54 if (!$token) $token = arcade_token_generate();
55 db_query("REPLACE INTO arcade_keys
56 VALUES (%d, %d, '%s', '%s', %d)",
57 $node->nid, $user->uid, $token, $key, time() );
58
59 $secure_str = "&pn_checksum=". $checksum .
60 "&pn_extravars=arcade~". $key .
61 "|". $token . "~1";
62 }
63 $node->flashnode['flashvars'] .= "pn_gid=". $node->nid .
64 "&pn_uname=". $user->name .
65 "&pn_domain=". $host .
66 "&pn_modvar=game_protocol";
67 if (isset($secure_str)) $node->flashnode['flashvars'] .= $secure_str;
68 }
69 }
70 break;
71
72
73 case 'insert':
74 // The node is being created (inserted in the database) or...
75 case 'update':
76 // The node is being updated.
77 if (isset($node->flashnode['orig_vars'])) {
78 $node->flashnode['flashvars'] = $node->flashnode['orig_vars'];
79 }
80
81 if (isset($node->is_game)) {
82 db_query("DELETE FROM {arcade_games} WHERE nid=%d", $node->nid);
83 }
84 if ($node->is_game > 0) {
85 db_query("INSERT INTO {arcade_games} (nid, game_type, game_path, secure) VALUES (%d, %d, '%s', %d)", $node->nid, $node->game_type, $node->game_path, $node->arcade_secure);
86 }
87 break;
88
89
90 case 'presave':
91 // The node passed validation and will soon be saved. Modules may use this
92 // to make changes to the node before it is saved to the database.
93 if ($node->is_game && $node->type == 'flashnode') {
94 $node->flashnode['base'] = $node->game_path ? $node->game_path : base_path();
95 }
96 break;
97
98 case 'delete':
99 // The node is being deleted.
100 db_query("DELETE FROM {arcade_games} WHERE nid=%d", $node->nid);
101 db_query("DELETE FROM {arcade_data} WHERE nid=%d", $node->nid);
102 break;
103 }
104 }
105
106 /**
107 * Helper function to generate token
108 */
109
110 function arcade_token_generate() {
111 $c = time();
112 $s = db_result(db_query("SELECT pass FROM {users} WHERE uid = 1"));
113 $i = mt_rand(0,23);
114 $s = substr($s, $i, 8);
115 $token = md5($s . $c);
116 variable_set('arcade_last_token', $c);
117 variable_set('arcade_token', $token);
118 return $token;
119 }
120
121 /**
122 * Implementation of hook_cron()
123 */
124 function arcade_cron() {
125 $now = time();
126 if ($now - variable_get('arcade_last_token', 0) > 800) {
127 arcade_token_generate();
128 }
129
130 db_query("DELETE FROM {arcade_keys} WHERE timestamp < %d", $now - 28800);
131 }
132
133
134 /**
135 * Helper function to get domain to send to Flash element
136 */
137 function arcade_getDomain() {
138 global $HTTP_SERVER_VARS;
139 if(!empty($HTTP_SERVER_VARS['HTTP_HOST'])){
140 $server = $HTTP_SERVER_VARS['HTTP_HOST'];
141 }else{
142 $server = $_SERVER['HTTP_HOST'];
143 }
144 $url = "http://".$server."/";
145
146 // get host name from URL
147 preg_match("/^(http:\/\/)?([^\/]+)/i",
148
149 $url, $matches);
150 $host = $matches[2];
151
152 $host = str_replace("www.", "", $host);
153 return $host;
154 }
155
156 /**
157 * Implementation of hook_form_alter().
158 */
159 function arcade_form_alter(&$form, $form_state, $form_id) {
160 if ($form_id == 'flashnode_node_form') {
161 $node = $form['#node'];
162 if (!isset($form['flashnode']['advanced']['#description'])) {
163 $form['flashnode']['advanced'] ['#description'] = '';
164 }
165 $form['flashnode']['advanced']['#description'] .= t('IMPORTANT: If you intend to use this node as a pnFlashGame with Arcade module, these fields will be filled in for you. You must leave them blank.');
166 if (isset($node->flashnode['orig_vars'])) {
167 $form['flashnode']['advanced']['flashvars']['#default_value'] = $node->flashnode['orig_vars'];
168 }
169 }
170
171 // Content type settings form.
172 if ($form_id == 'node_type_form') {
173
174 $form['arcade'] = array(
175 '#type' => 'fieldset',
176 '#title' => t('Arcade settings'),
177 '#collapsible' => TRUE,
178 '#collapsed' => TRUE,
179 );
180 $form['arcade']['is_game'] = array(
181 '#type' => 'radios',
182 '#title' => t('Game?'),
183 '#default_value' => variable_get('is_game_'. $form['#node_type']->type, 0),
184 '#options' => array(0 => t('No'), 1 => t('Yes')),
185 '#description' => t('Is this node type allowed to be a game?'),
186 );
187 }
188
189 // Node edit form.
190 if (isset($form['type'])) {
191 $type = $form['type']['#value'];
192 // If enabled adjust the form.
193 if ($form_id == $type .'_node_form' && variable_get('is_game_'. $type, 0)) {
194
195 $node = $form['#node'];
196
197 $form['arcade'] = array(
198 '#type' => 'fieldset',
199 '#title' => t('Arcade Settings'),
200 '#collapsible' => TRUE,
201 '#collapsed' => isset($node->is_game) && empty($node->is_game),
202 );
203 $form['arcade']['is_game'] = array(
204 '#type' => 'radios',
205 '#title' => t('Game?'),
206 '#default_value' => isset($node->is_game) ? $node->is_game : 0,
207 '#options' => array(0 => t('No'), 1 => t('Yes')),
208 '#description' => t('Is this node a game? (If you change from YES to NO, path & type will be lost.)'),
209 );
210 $form['arcade']['game_path'] = array(
211 '#type' => 'textfield',
212 '#title' => t('Path'),
213 '#default_value' => isset($node->game_path) ? $node->game_path : NULL,
214 '#description' => t('Path to game files. This is probably not required, for example if this is a Flashnode and your game is provided through a single SWF file identified by Flashnode module.')
215 );
216 $form['arcade']['game_type'] = array(
217 '#type' => 'radios',
218 '#title' => t('Game Type'),
219 '#default_value' => empty($node->game_type) ? 1 : $node->game_type,
220 '#options' => array(1 => t('High Score Wins'), 2 => t('Low Score Wins'), 3 => t('Longest Time Wins'), 4 => t('Shortest Time Wins') ),
221 '#description' => t('How do we identify the Best scores for this game?'),
222 );
223 $form['arcade']['arcade_secure'] = array(
224 '#type' => 'radios',
225 '#title' => t('Use secure mode?'),
226 '#default_value' => isset($node->arcade_secure) ? $node->arcade_secure : 0,
227 '#options' => array(0 => t('No'), 1 => t('Yes')),
228 '#description' => t('EXPERIMENTAL. Some pnFlashGames support a secure mode to hinder cheating. Selecting this option will prevent scores form being saved unless a security key is sent along with the score.'),
229 );
230
231 }
232 }
233 }
234
235
236 /**
237 * Implementation of hook_block().
238 */
239 function arcade_block($op = 'list', $delta = 0, $edit = array()) {
240 // The $op parameter determines what piece of information is being requested.
241 switch ($op) {
242 case 'list':
243 // If $op is "list", we just need to return a list of block descriptions.
244 // This is used to provide a list of possible blocks to the administrator,
245 // end users will not see these descriptions.
246 $blocks[0] = array(
247 'info' => t('Best Scores per Game'),
248 'status' => TRUE,
249 'region' => 'left',
250 );
251
252 $blocks[1] = array(
253 'info' => t('My Best Scores'),
254 'status' => TRUE,
255 'region' => 'left',
256 );
257
258 $blocks[2] = array(
259 'info' => t('Player\'s Best Scores'),
260 'status' => TRUE,
261 'region' => 'left',
262 'visibility' => 1,
263 'pages' => 'user/*',
264 );
265
266
267 return $blocks;
268
269 case 'view':
270 // If $op is "view", then we need to generate the block for display
271 // purposes. The $delta parameter tells us which block is being requested.
272 $block = array();
273
274 switch ($delta) {
275 case 0:
276 $node = menu_get_object();
277 if (!isset($node) || $node->is_game==0 || !user_access('view high scores')) {
278 break;
279 }
280
281 // The subject is displayed at the top of the block. Note that it
282 // should be passed through t() for translation.
283 $node = arg(0)=='node' ? node_load(arg(1)) : FALSE;
284 $block['subject'] = t("Best Scores for @title", array('@title' => $node->title));
285 // The content of the block is typically generated by calling a custom
286 // function.
287 $block['content'] = arcade_get_game_scores($node->nid);
288 break;
289
290 case 1:
291 if (!user_access('view high scores')) break;
292 global $user;
293 $block['subject'] = t('My Best Scores');
294 $block['content'] = arcade_get_player_scores($user->uid);
295 break;
296
297 case 2:
298 if (arg(0) != 'user') break;
299 $account = user_load(array('uid' => arg(1)));
300 global $user;
301 $block['subject'] = t('@user\'s Best Scores', array('@user' => $account->name));
302 if ($user->uid != $account->uid) $block['content'] = arcade_get_player_scores($account->uid);
303 break;
304 }
305 return $block;
306 }
307 }
308
309 /**
310 * Displays High scores for game with game id $nid
311 */
312 function arcade_get_game_scores($nid) {
313 static $name_cache;
314 //get scores from database
315 $result = db_query_range("SELECT uid, score FROM {arcade_data} WHERE nid=%d AND score IS NOT NULL", $nid, 0, 10);
316
317 //construct an array of UserName => Score
318 $highscores = array();
319 while ($score = db_fetch_object($result)) {
320 if (isset($name_cache[$score->uid])) {
321 $uname = $name_cache[$score->uid];
322 } else {
323 $uname = db_result(db_query("SELECT name FROM {users} WHERE uid=%d", $score->uid));
324 $name_cache[$score->uid] = $uname;
325 }
326 $highscores[l($uname, 'user/'. $score->uid)] = $score->score;
327 }
328
329 if (count($highscores) < 1) return; //bail early if we found nothing
330
331 //sort the scores, based on the game type
332 $game_type = db_result(db_query("SELECT game_type FROM {arcade_games} WHERE nid = %d", $nid));
333 if ($game_type==2 || $game_type==4) {
334 asort($highscores, SORT_NUMERIC);
335 } else {
336 arsort($highscores, SORT_NUMERIC);
337 }
338
339 //render the array as HTML
340 return theme('arcade_list_scores', $highscores);
341 }
342
343 /**
344 * Displays High scores for player with user id $uid
345 */
346 function arcade_get_player_scores($uid) {
347 //get scores from database
348 $result = db_query_range("SELECT nid, score FROM {arcade_data} WHERE uid=%d AND score IS NOT NULL ORDER BY score DESC", $uid, 0, 10);
349
350 //construct an array of GameName => Score
351 $highscores = array();
352 while ($score = db_fetch_object($result)) {
353 $game = node_load($score->nid);
354 $highscores[l($game->title, 'node/'.$score->nid)] = $score->score;
355 }
356 if (count($highscores) < 1) return; //bail early if we found nothing
357
358 //render the array as HTML
359 return theme('arcade_list_scores', $highscores);
360 }
361
362 /**
363 * Implementation of hook_theme()
364 */
365 function arcade_theme($existing, $type, $theme, $path) {
366 return array(
367 'arcade_list_scores' => array (
368 'arguments' => array('scores' => NULL),
369 ),
370 );
371 }
372
373
374 /**
375 * Render HTML display of a score list array in the form of Name => Score
376 */
377 function theme_arcade_list_scores($scores) {
378 $output = "<ul>";
379 foreach ($scores AS $name => $value) {
380 $output .= "<li> $name - $value</li>";
381 }
382 $output .= "</ul>";
383
384 return $output;
385 }
386
387 function arcade_get_checksum($file){
388 if($fp = fopen($file, 'r')){
389 $filecontent = fread($fp, filesize($file));
390 fclose($fp);
391 return md5($filecontent);
392 }else{
393 return false;
394 }
395 }

  ViewVC Help
Powered by ViewVC 1.1.2