i wonder....
[mudd.git] / mud.php
1 <?php
2
3 abstract class model {
4
5 private $config_file = '/etc/mud.ini';
6 private $db;
7
8 public function __construct() {
9 $config = parse_ini_file($this->config_file, true);
10 $this->db = new mysqli(
11 $config['database']['domain'],
12 $config['database']['user'],
13 $config['database']['password'],
14 $config['database']['database']);
15 if (mysqli_connect_errno()) {
16 echo "Problem connecting to database: ";
17 echo mysqli_connect_error();
18 exit();
19 }
20 }
21
22 public function query() {
23 $args = func_get_args();
24 $statement = $this->db->prepare(array_shift($args));
25 if ($args) call_user_func_array(array($statement, 'bind_param'), &$args);
26 $statement->execute();
27 $statement->store_result();
28 $statement->store_result();
29 $data = $statement->result_metadata();
30 $return = $row = $fields = array();
31 $fields[0] = &$statement;
32 while($field = $data->fetch_field())
33 $fields[] = &$row[$field->name];
34 call_user_func_array("mysqli_stmt_bind_result", $fields);
35 $i = 0;
36 while ($statement->fetch()) {
37 foreach ($row as $key=>$value) $return[$i][$key] = $value;
38 $i++;
39 }
40 $statement->free_result();
41 return $return;
42 }
43
44 public function insert() {
45 $args = func_get_args();
46 $statement = $this->db->prepare(array_shift($args));
47 call_user_func_array(array($statement, 'bind_param'), &$args);
48 $statement->execute();
49 return $this->db->insert_id;
50 }
51
52 }
53
54 class universe {
55 public $rows = 30;
56 public $columns = 30;
57 public $rooms = array();
58
59 public function __construct($db) {
60 $rooms = $db->query("SELECT id,x,y,state FROM rooms");
61 if ($rooms) {
62 foreach ($rooms as $room) {
63 $this->rooms[$room['x']][$room['y']] =
64 array('id' => $room['id'], 'state' => $room['state']);
65 }
66 } else {
67 $sql = 'INSERT INTO rooms (x,y,state) VALUES(?,?,?)';
68 $types = 'iii';
69 for ($x = 0; $x < $this->columns; $x++) {
70 $column = array();
71 for ($y = 0; $y < $this->rows; $y++) {
72 $state = (rand(0, 9) < 2 ? true : false);
73 $id = $db->insert($sql, $types, $x, $y, $state);
74 $this->rooms[$x][$y] =
75 array('id' => $id, 'state' => $state);
76 }
77 }
78 }
79 }
80
81 public function serialize() {
82 $serial = array();
83 for ($x = 0; $x < $this->columns; $x++) {
84 for ($y = 0; $y < $this->rows; $y++) {
85 $serial[$x][$y] = $this->rooms[$x][$y]['state'];
86 }
87 }
88 return $serial;
89 }
90
91 }
92
93 class player {
94
95 public $id;
96 public $name;
97 public $room;
98 public $x;
99 public $y;
100
101 public function __construct($db) {
102 $player = $db->query(
103 'SELECT players.id, players.name, players.room, rooms.x, rooms.y'
104 . ' FROM players LEFT JOIN rooms ON players.room = rooms.id'
105 . ' WHERE players.id = ?',
106 'i', $_SESSION['id']
107 );
108 $player = $player[0];
109 $this->id = $player['id'];
110 $this->name = $player['name'];
111 $this->room = $player['room'];
112 $this->x = $player['x'];
113 $this->y = $player['y'];
114 }
115
116 }
117
118 class mud extends model {
119
120 private $universe;
121
122 public function __construct() {
123 parent::__construct();
124 session_start();
125 $this->universe = new universe($this);
126 }
127
128 private function join() {
129 $x = 0;
130 $y = 0;
131 if (isset($_SESSION['id'])) {
132 $x = $this->player->x;
133 $y = $this->player->y;
134 $id = $this->player->id;
135 } else {
136 do {
137 $x = rand(0, count($this->universe->rooms)-1);
138 $y = rand(0, count($this->universe->rooms[0])-1);
139 } while ($this->universe->rooms[$x][$y]['state']);
140 $id = $this->insert('INSERT INTO players (name,room) VALUES(?,?)',
141 'si', 'majuscule', $this->universe->rooms[$x][$y]['id']);
142 $_SESSION['id'] = $id;
143 }
144 return array('x' => $x, 'y' => $y, 'id' => $id);
145 }
146
147 private function yell($msg) {
148 $this->insert(
149 'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)',
150 'ssii', $msg, 'yell', $this->player->room, $this->player->id);
151 }
152
153 // private function tell($msg) {
154 // // lookup dest
155 // $this->insert(
156 // 'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)',
157 // 'ssii', $msg, 'tell', $this->player->room, $this->player->id);
158 // }
159
160 private function say($msg) {
161 $this->insert(
162 'INSERT INTO messages (message,type,room,source) VALUES(?,?,?,?)',
163 'ssii', $msg, 'say', $this->player->room, $this->player->id);
164 }
165
166 private function move() {
167 // ahhhhhhhhhhhhhhhhhhhh
168 }
169
170 private function poll() {
171 $time = isset($_SESSION['last_polled']) ? $_SESSION['last_polled'] : 0;
172 $messages = $this->query(
173 'SELECT message, type, name, sent, players.id FROM messages LEFT JOIN players'
174 . ' ON destination = players.id'
175 . ' OR source = players.id'
176 . ' WHERE TIMESTAMPDIFF(MINUTE, sent, NOW()) < 5'
177 . ' AND UNIX_TIMESTAMP(sent) >= ?'
178 . ' AND (type = "yell"'
179 . ' OR (type = "tell" AND destination = ?)'
180 . ' OR (type = "say" AND messages.room = ?))',
181 'iii', $time, $this->player->id, $this->player->room);
182 $_SESSION['last_polled'] = time();
183 return $messages;
184 }
185
186 public function response($content) {
187 header('Content-Type: application/json');
188 echo json_encode($content);
189 }
190
191 public function command($cmd) {
192 if (!$_GET['cmd'])
193 $this->error(400, 'Missing command: expected `cmd` field');
194 if ($_GET['cmd'] != 'join' && $_GET['cmd'] != 'start' && !isset($_SESSION['id']))
195 $this->error(401, 'Missing user ID: please join first');
196 if (isset($_SESSION['id'])) $this->player = new player($this);
197 switch ($cmd) {
198 case 'start':
199 $this->response($this->universe->serialize());
200 // $this->response($this->universe->serialize($_GET['restart']));
201 break;
202 case 'join':
203 $this->response($this->join());
204 break;
205 case 'move':
206 $this->response(array('valid' => $this->move()));
207 break;
208 case 'tell':
209 $this->tell();
210 break;
211 case 'yell':
212 $this->yell($_GET['msg']);
213 break;
214 case 'say':
215 $this->say();
216 break;
217 case 'tell':
218 $this->tell();
219 break;
220 case 'poll':
221 echo json_encode($this->poll());
222 break;
223 // case 'respawn':
224 // session_destroy()
225 // session_start()
226 // $this->response($this->join());
227 default:
228 $this->error(400, 'Unknown command');
229 }
230 }
231
232 private function error($status, $msg) {
233 header("HTTP/1.0 $status");
234 echo $msg;
235 }
236
237 }
238
239 $mud = new mud();
240 $mud->command($_GET['cmd']);
241
242 ?>