Move conf outside of webroot; fix func invocation
[mudd.git] / mud.php
diff --git a/mud.php b/mud.php
index 9e347a3..4309fef 100644 (file)
--- a/mud.php
+++ b/mud.php
@@ -22,7 +22,8 @@ abstract class model {
     public function query() {
         $args = func_get_args();
         $statement = $this->db->prepare(array_shift($args));
-        if ($args) call_user_func_array(array($statement, 'bind_param'), &$args);
+        #if ($args) call_user_func_array(array($statement, 'bind_param'), &$args);
+        if ($args) call_user_func_array(array($statement, 'bind_param'), $args);
         $statement->execute();
         $statement->store_result();
         $statement->store_result();
@@ -44,7 +45,15 @@ abstract class model {
     public function insert() {
         $args = func_get_args();
         $statement = $this->db->prepare(array_shift($args));
-        call_user_func_array(array($statement, 'bind_param'), &$args);
+        call_user_func_array(array($statement, 'bind_param'), $args);
+        $statement->execute();
+        return $this->db->insert_id;
+    }
+
+    public function update() {
+        $args = func_get_args();
+        $statement = $this->db->prepare(array_shift($args));
+        call_user_func_array(array($statement, 'bind_param'), $args);
         $statement->execute();
         return $this->db->insert_id;
     }
@@ -57,7 +66,7 @@ class universe {
     public $rooms = array();
 
     public function __construct($db) {
-        $rooms = $db->query("SELECT id,x,y,state FROM rooms");
+        $rooms = $db->query('SELECT id,x,y,state FROM rooms');
         if ($rooms) {
             foreach ($rooms as $room) {
                 $this->rooms[$room['x']][$room['y']] =
@@ -126,30 +135,64 @@ class mud extends model {
     }
 
     private function join() {
-        $x = 0;
-        $y = 0;
-        if (isset($_SESSION['id'])) {
-            $x = $this->player->x;
-            $y = $this->player->y;
-            $id = $this->player->id;
-        } else {
-            do {
-                $x = rand(0, count($this->universe->rooms)-1);
-                $y = rand(0, count($this->universe->rooms[0])-1);
-            } while ($this->universe->rooms[$x][$y]['state']);
-            $id = $this->insert('INSERT INTO players (name,room) VALUES(?,?)',
-                                'si', 'majuscule', $this->universe->rooms[$x][$y]['id']);
-            $_SESSION['id'] = $id;
-        }
-        return array('x' => $x, 'y' => $y, 'id' => $id);
+        $x = $y = 0;
+        do {
+            $x = rand(0, count($this->universe->rooms)-1);
+            $y = rand(0, count($this->universe->rooms[0])-1);
+        } while ($this->universe->rooms[$x][$y]['state']);
+        $id = $this->insert('INSERT INTO players (name,room) VALUES(?,?)',
+                            'si', $_GET['name'], $this->universe->rooms[$x][$y]['id']);
+        $_SESSION['id'] = $id;
+        //$others = $this->query('SELECT id, room FROM players WHERE id != ?', 'i', $this->player->id);
+        return array('x' => $x, 'y' => $y, 'id' => $id, 'poll' => $this->poll());
     }
 
     private function yell($msg) {
+        if (!$msg) $this->error('400', 'expected `msg` field');
         $this->insert(
             'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)',
             'ssii', $msg, 'yell', $this->player->room, $this->player->id);
     }
 
+    private function say($msg) {
+        if (!$msg) $this->error('400', 'expected `dest` field');
+        $this->insert(
+            'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)',
+            'ssii', $msg, 'say', $this->player->room, $this->player->id);
+    }
+
+    private function tell($dest, $msg) {
+        if (!$dest || !$msg) $this->error('400', 'expected `dest` and `msg` fields');
+        $player = $this->query('SELECT id FROM players where name = ?', 's', $dest);
+        if (!($player && $player['id']))
+            $this->error(400, "could not find a player with `name` == $dest");
+        $this->insert(
+            'INSERT INTO messages (message,type,destination,source) VALUES(?,?,?,?)',
+            'ssii', $msg, 'say', $player['id'], $this->player->id);
+    }
+
+    private function move($direction) {
+        $directions = array(
+            'north' => array('x' => $this->player->x,   'y' => $this->player->y-1),
+            'east'  => array('x' => $this->player->x+1, 'y' => $this->player->y),
+            'south' => array('x' => $this->player->x,   'y' => $this->player->y+1),
+            'west'  => array('x' => $this->player->x-1, 'y' => $this->player->y),
+        );
+        if ($directions[$direction]) {
+            $rooms = $this->query(
+                'SELECT id, state, description FROM rooms WHERE x = ? and y = ?',
+                'ii', $directions[$direction]['x'], $directions[$direction]['y']);
+            if ($rooms[0] && !$rooms[0]['state']) {
+                $this->update('UPDATE players SET room = ? WHERE players.id = ?',
+                    'si', $rooms[0]['id'], $this->player->id);
+                return array('description' => $rooms[0]['description']);
+            } else {
+                $this->error(403, 'your path is blocked');
+            }
+        } else
+            $this->error(400, 'expected `direction` field with value {north|east|south|west}');
+    }
+
     private function poll() {
         $time = isset($_SESSION['last_polled']) ? $_SESSION['last_polled'] : 0;
         $messages = $this->query(
@@ -162,8 +205,12 @@ class mud extends model {
                 . ' OR (type = "tell" AND destination = ?)'
                 . ' OR (type = "say" AND messages.room = ?))',
             'iii', $time, $this->player->id, $this->player->room);
+        $players = $this->query(
+            'SELECT players.id, name, x ,y '
+            . 'FROM players JOIN rooms '
+            . 'ON players.room = rooms.id');
         $_SESSION['last_polled'] = time();
-        return $messages;
+        return array('messages' => $messages, 'players' => $players);
     }
 
     public function response($content) {
@@ -174,7 +221,8 @@ class mud extends model {
     public function command($cmd) {
         if (!$_GET['cmd'])
             $this->error(400, 'Missing command: expected `cmd` field');
-        if ($_GET['cmd'] != 'join' && $_GET['cmd'] != 'start' && !isset($_SESSION['id']))
+        if (($_GET['cmd'] != 'join' && $_GET['cmd'] != 'kick')
+            && $_GET['cmd'] != 'start' && !isset($_SESSION['id']))
             $this->error(401, 'Missing user ID: please join first');
         if (isset($_SESSION['id'])) $this->player = new player($this);
         switch ($cmd) {
@@ -185,31 +233,35 @@ class mud extends model {
                 $this->response($this->join());
                 break;
             case 'move':
-                $this->response(array('valid' => $this->move()));
+                $this->response($this->move($_GET['direction']));
                 break;
             case 'tell':
-                $this->tell();
+                $this->tell($_GET['msg']);
                 break;
             case 'yell':
                 $this->yell($_GET['msg']);
                 break;
             case 'say':
-                $this->say();
+                $this->say($_GET['msg']);
                 break;
             case 'tell':
-                $this->tell();
+                $this->tell($_GET['dest'], $_GET['msg']);
                 break;
             case 'poll':
-                echo json_encode($this->poll());
+                $this->response($this->poll());
+                break;
+            case 'kick':
+                $this->update('DELETE FROM players');
                 break;
             default:
-                $this->error(400, 'Unknown command');
+                $this->error(400, 'unknown command');
         }
     }
 
     private function error($status, $msg) {
         header("HTTP/1.0 $status");
         echo $msg;
+        exit;
     }
 
 }