X-Git-Url: https://disinclined.org/git/?a=blobdiff_plain;ds=sidebyside;f=mud.php;fp=mud.php;h=9e347a37a9c00360a647b3a9883363d36270ee25;hb=ac86d15fc911ea899a123b1fc3027bf12aa6809e;hp=0000000000000000000000000000000000000000;hpb=768cba736b242e05c2d158704fc29b6c7d958916;p=mudd.git diff --git a/mud.php b/mud.php new file mode 100644 index 0000000..9e347a3 --- /dev/null +++ b/mud.php @@ -0,0 +1,220 @@ +config_file, true); + $this->db = new mysqli( + $config['database']['domain'], + $config['database']['user'], + $config['database']['password'], + $config['database']['database']); + if (mysqli_connect_errno()) { + echo "Problem connecting to database: "; + echo mysqli_connect_error(); + exit(); + } + } + + 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); + $statement->execute(); + $statement->store_result(); + $statement->store_result(); + $data = $statement->result_metadata(); + $return = $row = $fields = array(); + $fields[0] = &$statement; + while($field = $data->fetch_field()) + $fields[] = &$row[$field->name]; + call_user_func_array("mysqli_stmt_bind_result", $fields); + $i = 0; + while ($statement->fetch()) { + foreach ($row as $key=>$value) $return[$i][$key] = $value; + $i++; + } + $statement->free_result(); + return $return; + } + + public function insert() { + $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; + } + +} + +class universe { + public $rows = 30; + public $columns = 30; + public $rooms = array(); + + public function __construct($db) { + $rooms = $db->query("SELECT id,x,y,state FROM rooms"); + if ($rooms) { + foreach ($rooms as $room) { + $this->rooms[$room['x']][$room['y']] = + array('id' => $room['id'], 'state' => $room['state']); + } + } else { + $sql = 'INSERT INTO rooms (x,y,state) VALUES(?,?,?)'; + $types = 'iii'; + for ($x = 0; $x < $this->columns; $x++) { + $column = array(); + for ($y = 0; $y < $this->rows; $y++) { + $state = (rand(0, 9) < 2 ? true : false); + $id = $db->insert($sql, $types, $x, $y, $state); + $this->rooms[$x][$y] = + array('id' => $id, 'state' => $state); + } + } + } + } + + public function serialize() { + $serial = array(); + for ($x = 0; $x < $this->columns; $x++) { + for ($y = 0; $y < $this->rows; $y++) { + $serial[$x][$y] = $this->rooms[$x][$y]['state']; + } + } + return $serial; + } + +} + +class player { + + public $id; + public $name; + public $room; + public $x; + public $y; + + public function __construct($db) { + $player = $db->query( + 'SELECT players.id, players.name, players.room, rooms.x, rooms.y' + . ' FROM players LEFT JOIN rooms ON players.room = rooms.id' + . ' WHERE players.id = ?', + 'i', $_SESSION['id'] + ); + $player = $player[0]; + $this->id = $player['id']; + $this->name = $player['name']; + $this->room = $player['room']; + $this->x = $player['x']; + $this->y = $player['y']; + } + +} + +class mud extends model { + + private $universe; + + public function __construct() { + parent::__construct(); + session_start(); + $this->universe = new universe($this); + } + + 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); + } + + private function yell($msg) { + $this->insert( + 'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)', + 'ssii', $msg, 'yell', $this->player->room, $this->player->id); + } + + private function poll() { + $time = isset($_SESSION['last_polled']) ? $_SESSION['last_polled'] : 0; + $messages = $this->query( + 'SELECT message, type, name, sent, players.id FROM messages LEFT JOIN players' + . ' ON destination = players.id' + . ' OR source = players.id' + . ' WHERE TIMESTAMPDIFF(MINUTE, sent, NOW()) < 5' + . ' AND UNIX_TIMESTAMP(sent) >= ?' + . ' AND (type = "yell"' + . ' OR (type = "tell" AND destination = ?)' + . ' OR (type = "say" AND messages.room = ?))', + 'iii', $time, $this->player->id, $this->player->room); + $_SESSION['last_polled'] = time(); + return $messages; + } + + public function response($content) { + header('Content-Type: application/json'); + echo json_encode($content); + } + + 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'])) + $this->error(401, 'Missing user ID: please join first'); + if (isset($_SESSION['id'])) $this->player = new player($this); + switch ($cmd) { + case 'start': + $this->response($this->universe->serialize()); + break; + case 'join': + $this->response($this->join()); + break; + case 'move': + $this->response(array('valid' => $this->move())); + break; + case 'tell': + $this->tell(); + break; + case 'yell': + $this->yell($_GET['msg']); + break; + case 'say': + $this->say(); + break; + case 'tell': + $this->tell(); + break; + case 'poll': + echo json_encode($this->poll()); + break; + default: + $this->error(400, 'Unknown command'); + } + } + + private function error($status, $msg) { + header("HTTP/1.0 $status"); + echo $msg; + } + +} + +$mud = new mud(); +$mud->command($_GET['cmd']); + +?>