aboutsummaryrefslogtreecommitdiffstats
path: root/toj/php
diff options
context:
space:
mode:
Diffstat (limited to 'toj/php')
-rw-r--r--toj/php/_json.php3
-rw-r--r--toj/php/_test.php20
-rw-r--r--toj/php/common.inc.php7
-rw-r--r--toj/php/connect.inc.php40
-rw-r--r--toj/php/event.inc.php71
-rw-r--r--toj/php/event.php24
-rw-r--r--toj/php/event_exec.cpp89
-rw-r--r--toj/php/event_exec.h12
-rw-r--r--toj/php/notice.inc.php244
-rw-r--r--toj/php/notice.php110
-rw-r--r--toj/php/problem.inc.php252
-rw-r--r--toj/php/problem.php140
-rw-r--r--toj/php/pzreadtest.php9
-rw-r--r--toj/php/sqlib.inc.php5
-rw-r--r--toj/php/sqlib_scoreboard.inc.php239
-rw-r--r--toj/php/square.inc.php229
-rw-r--r--toj/php/square.php350
-rw-r--r--toj/php/status.inc.php133
-rw-r--r--toj/php/status.php70
-rw-r--r--toj/php/step.inc.php17
-rw-r--r--toj/php/step.php64
-rw-r--r--toj/php/teamt.php28
-rw-r--r--toj/php/test.php32
-rw-r--r--toj/php/user.inc.php212
-rw-r--r--toj/php/user.php160
25 files changed, 2560 insertions, 0 deletions
diff --git a/toj/php/_json.php b/toj/php/_json.php
new file mode 100644
index 0000000..b3c443e
--- /dev/null
+++ b/toj/php/_json.php
@@ -0,0 +1,3 @@
+<?php
+echo json_encode("#include <stdio.h>\nint main(){while(scanf(\"%d%d\", &a, &b)==2)printf(\"%d\n\", a+b); return 0;}\n");
+?>
diff --git a/toj/php/_test.php b/toj/php/_test.php
new file mode 100644
index 0000000..5ce8271
--- /dev/null
+++ b/toj/php/_test.php
@@ -0,0 +1,20 @@
+<form action="notice.php" method=post>
+ <input type='hidden' value='{"uid":111}' name='data'>
+ <input type='hidden' value='count' name='action'>
+ <input type='submit' value='ti jiao count'>
+</form>
+<form action="notice.php" method=post>
+ <input type='text' value='{"uid":111}' name='data'>
+ <input type='hidden' value='get' name='action'>
+ <input type='submit' value='ti jiao get'>
+</form>
+<form action="notice.php" method=post>
+ <input type='hidden' value='{"uid":111}' name='data'>
+ <input type='hidden' value='clear' name='action'>
+ <input type='submit' value='ti jiao clear'>
+</form>
+<form action="notice.php" method=post>
+ <input type='text' value='{"uid":111,"type":1,"value":111,"context":"aaaaaa"}' name='data'>
+ <input type='hidden' value='add' name='action'>
+ <input type='submit' value='ti jiao add'>
+</form>
diff --git a/toj/php/common.inc.php b/toj/php/common.inc.php
new file mode 100644
index 0000000..d31a596
--- /dev/null
+++ b/toj/php/common.inc.php
@@ -0,0 +1,7 @@
+<?php
+
+date_default_timezone_set('Asia/Taipei');
+
+require('connect.inc.php');
+
+?>
diff --git a/toj/php/connect.inc.php b/toj/php/connect.inc.php
new file mode 100644
index 0000000..3eebe89
--- /dev/null
+++ b/toj/php/connect.inc.php
@@ -0,0 +1,40 @@
+<?php
+
+define('DB_NAME','xxxxx');
+define('DB_USER','xxxxx');
+define('DB_PASSWORD','xxxxx');
+define('SEC_SALT','xxxxx');
+
+define('SMTP_HOST','xxxxx');
+define('SMTP_USER','xxxxx');
+define('SMTP_PASS','xxxxx');
+
+const CENTER_SOCKET_PORT = 2501;
+
+function sec_is_login()
+{
+ if(!isset($_COOKIE['uid']) || !isset($_COOKIE['usec'])){
+ return false;
+ }
+
+ $userid = $_COOKIE['uid'];
+ $usersec = $_COOKIE['usec'];
+
+ if($userid == '' || $usersec == '' || strval(intval($userid)) != $userid || hash('sha512',$userid.SEC_SALT) != $usersec){
+ return false;
+ }
+
+ return true;
+}
+
+function db_connect($dbn = DB_NAME)
+{
+ return pg_connect('host=localhost port=5432 dbname='.$dbn.' user='.DB_USER.' password='.DB_PASSWORD);
+}
+
+function db_close($sqlcx)
+{
+ pg_close($sqlcx);
+}
+
+?>
diff --git a/toj/php/event.inc.php b/toj/php/event.inc.php
new file mode 100644
index 0000000..9d2a23c
--- /dev/null
+++ b/toj/php/event.inc.php
@@ -0,0 +1,71 @@
+<?php
+class event
+{
+ private static $white_list;
+
+ private static function init()
+ {
+ event::$white_list = array('10.8.0.2');
+ }
+
+ // execute function $name in file $fname
+ // if want to call a function of a class, have 2 choice:
+ // 1. pass an array as $name, put every level of class in it, like:
+ // A::B::C() should be passed like array("A", "B", "C").
+ // 2. pass a string with :: directly, it will be automatically
+ // translated.
+ // return value will be FALSE on failure, return value of target
+ // function otherwise. NULL when no return value.
+ public static function exec_func($fname, $name, $arg)
+ {
+ if(!file_exists($fname))
+ {
+ return false;
+ }
+ require_once($fname);
+ if(is_string($name) && strpos($name, ":") !== FALSE)
+ {
+ $name = preg_split("/::/", $name);
+ }
+ if(is_string($name) && !is_callable($name))
+ {
+ return false;
+ }
+ if(is_array($name) && !is_callable(join($name, "::")))
+ {
+ return false;
+ }
+ if($arg == NULL)
+ {
+ $res = call_user_func($name);
+ }
+ else
+ {
+ $res = call_user_func_array($name, $arg);
+ }
+ if($res === false)
+ {
+ return false;
+ }
+ return $res;
+ }
+
+ public static function validate_ip()
+ {
+ event::init();
+ if (!empty($_SERVER['HTTP_CLIENT_IP']))
+ {
+ $ip=$_SERVER['HTTP_CLIENT_IP'];
+ }
+ else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
+ {
+ $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
+ }
+ else
+ {
+ $ip=$_SERVER['REMOTE_ADDR'];
+ }
+ return in_array($ip, event::$white_list);
+ }
+}
+?>
diff --git a/toj/php/event.php b/toj/php/event.php
new file mode 100644
index 0000000..e121287
--- /dev/null
+++ b/toj/php/event.php
@@ -0,0 +1,24 @@
+<?php
+ require_once('event.inc.php');
+ if (!empty($_SERVER['HTTP_CLIENT_IP']))
+ $ip=$_SERVER['HTTP_CLIENT_IP'];
+ else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
+ $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
+ else
+ $ip=$_SERVER['REMOTE_ADDR'];
+ if(!event::validate_ip())
+ {
+ exit;
+ }
+ $fname = $_POST['fname'];
+ $name = $_POST['name'];
+ $arg = json_decode($_POST['arg']);
+ if(event::exec_func($fname, $name, $arg) === false)
+ {
+ echo "false";
+ }
+ else
+ {
+ echo "true";
+ }
+?>
diff --git a/toj/php/event_exec.cpp b/toj/php/event_exec.cpp
new file mode 100644
index 0000000..25d7944
--- /dev/null
+++ b/toj/php/event_exec.cpp
@@ -0,0 +1,89 @@
+#include "event_exec.h"
+
+#define EVENT_BUFLEN 1005
+#define EVENT_URL "http://10.8.0.2/toj/php/event.php"
+
+struct event_handle
+{
+ int init, plen, blen;
+ char *post, *buf;
+ pthread_mutex_t mutex;
+ CURL *handle;
+};
+
+static struct event_handle conn;
+
+size_t event_write_cb(void *in, size_t siz, size_t nb, void *buf)
+{
+ int len;
+ len = siz*nb+1;
+ if(len > conn.blen)
+ {
+ len = conn.blen-1;
+ }
+ memcpy(buf, in, len);
+ ((char*)buf)[len] = 0;
+ return siz*nb;
+}
+
+int event_init()
+{
+ if(conn.init)
+ {
+ return 0;
+ }
+ conn.plen = conn.blen = EVENT_BUFLEN;
+ conn.post = (char*)malloc(EVENT_BUFLEN);
+ conn.buf = (char*)malloc(EVENT_BUFLEN);
+ curl_global_init(CURL_GLOBAL_ALL);
+ conn.handle = curl_easy_init();
+ curl_easy_setopt(conn.handle, CURLOPT_URL, EVENT_URL);
+ curl_easy_setopt(conn.handle, CURLOPT_WRITEFUNCTION, event_write_cb);
+ curl_easy_setopt(conn.handle, CURLOPT_WRITEDATA, conn.buf);
+ pthread_mutex_init(&conn.mutex, NULL);
+ conn.init = 1;
+ return 1;
+}
+
+int event_exec(const char *fname, const char *name, const char *arg)
+{
+ int res, len;
+ char *t;
+ event_init();
+ if(pthread_mutex_lock(&conn.mutex) == 0)
+ {
+ len = 0;
+ len += strlen(fname)+6;
+ len += strlen(name)+6;
+ len += strlen(arg)+6;
+ if(len > conn.plen)
+ {
+ t = (char*)malloc(len);
+ if(!t)
+ {
+ pthread_mutex_unlock(&conn.mutex);
+ return 0;
+ }
+ free(conn.post);
+ conn.post = t;
+ conn.plen = len;
+ }
+ sprintf(conn.post, "fname=%s&name=%s&arg=%s", fname, name, arg);
+ curl_easy_setopt(conn.handle, CURLOPT_POSTFIELDS, conn.post);
+ res = curl_easy_perform(conn.handle);
+ if(res)
+ {
+ pthread_mutex_unlock(&conn.mutex);
+ return 0;
+ }
+ fprintf(stderr, "%s\n", conn.buf);
+ if(!strcmp(conn.buf, "true"))
+ {
+ pthread_mutex_unlock(&conn.mutex);
+ return 1;
+ }
+
+ pthread_mutex_unlock(&conn.mutex);
+ }
+ return 0;
+}
diff --git a/toj/php/event_exec.h b/toj/php/event_exec.h
new file mode 100644
index 0000000..aec1acb
--- /dev/null
+++ b/toj/php/event_exec.h
@@ -0,0 +1,12 @@
+#ifndef EVENT_EXEC
+#define EVENT_EXEC
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <curl/curl.h>
+#include <pthread.h>
+
+int event_exec(const char *fname, const char *name, const char *arg);
+
+#endif
diff --git a/toj/php/notice.inc.php b/toj/php/notice.inc.php
new file mode 100644
index 0000000..dbf47cc
--- /dev/null
+++ b/toj/php/notice.inc.php
@@ -0,0 +1,244 @@
+<?php
+require_once('common.inc.php');
+require_once('user.inc.php');
+
+const NOTICE_DEF_LIM = 5;
+const NOTICE_MAX_LIM = 30;
+
+const NOTICE_ACT_CNT = 1;
+const NOTICE_ACT_NEW = 2;
+const NOTICE_ACT_OLD = 4;
+
+const NOTICE_TYP_USR = 1;
+const NOTICE_TYP_PRO = 2;
+const NOTICE_TYP_SQR = 3;
+const NOTICE_TYP_ALL = 255;
+
+class notice
+{
+ private static function ins_uid($sqlc, $uid)
+ {
+ $sqlstr = 'INSERT INTO "notice_cache" ("uid", "tim", "cnt", "tmp", "rsv") VALUES ($1, $2, $3, $4, $5) RETURNING *;';
+ $sqlarr = array($uid, date("Y-m-d H:i:s"), 0, "0", "0");
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ pg_free_result($sqlr);
+ return $ret;
+ }
+
+ public static function is_match($sqlc, $uid, &$not)
+ {
+ if($not->typ == NOTICE_TYP_ALL)
+ {
+ return true;
+ }
+ if($not->typ == NOTICE_TYP_USR)
+ {
+ return $uid == intval($not->val);
+ }
+ require_once('event.inc.php');
+ if($not->typ == NOTICE_TYP_PRO)
+ {
+ if(!event::exec_func('problem.inc.php', 'problem::is_available', array($sqlc, $not->val, $uid)))
+ {
+ return false;
+ }
+ return true;
+ }
+ else if($not->typ == NOTICE_TYP_SQR)
+ {
+ $ret = event::exec_func('square.inc.php', 'square::get_user_relationship', array($sqlc, $uid, $not->val));
+ if($ret >= SQUARE_USER_ACTIVE)
+ {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ private static function update($sqlc, $uid, &$tar, &$arr)
+ {
+ if(count($arr) <= 0)
+ {
+ return false;
+ }
+ $sqlstr = 'UPDATE "notice_cache" SET "tmp"=$1, "cnt"=$2, "tim"=$4 WHERE "uid"=$3 RETURNING *;';
+ $sqlarr = array($arr[0], intval($tar->cnt)+count($arr), $uid, date('Y-m-d H:i:s'));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ pg_free_result($sqlr);
+ foreach($arr as $it)
+ {
+ $sqlstr = 'INSERT INTO "user_notice" ("uid", "nid") VALUES ($1, $2);';
+ $sqlarr = array(intval($uid), intval($it));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ pg_free_result($sqlr);
+ }
+ return $ret;
+ }
+
+ private static function check_new($sqlc, $uid)
+ {
+ $sqlstr = 'SELECT * FROM "notice_cache" WHERE "uid"=$1;';
+ $sqlarr = array($uid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ if($ret === false)
+ {
+ $ret = notice::ins_uid($sqlc, $uid);
+ }
+ pg_free_result($sqlr);
+ $sqlstr = 'SELECT * FROM "notice" WHERE "nid" > $1 ORDER BY "tim";';
+ $sqlarr = array(intval($ret->tmp));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $buf = array();
+ while($row = pg_fetch_object($sqlr))
+ {
+ if(self::is_match($sqlc, $uid, $row))
+ {
+ array_unshift($buf, $row->nid);
+ }
+ }
+ pg_free_result($sqlr);
+ if(count($buf) > 0)
+ {
+ return self::update($sqlc, $uid, $ret, $buf);
+ }
+ return $ret;
+ }
+
+ // **warning**: this function will clear notice count of uid!!
+ public static function get($sqlc, $uid, $typ, $arg1, $arg2)
+ {
+ $uid = intval($uid);
+ if(!$uid || !$sqlc)
+ {
+ return false;
+ }
+ $ret = self::check_new($sqlc, $uid);
+ if($typ == NOTICE_ACT_CNT)
+ {
+ return intval($ret->cnt);
+ }
+ else if($typ == NOTICE_ACT_NEW)
+ {
+ if($ret->cnt == 0)
+ {
+ return array();
+ }
+ $sqlstr = 'SELECT "nid" FROM "user_notice" WHERE "uid"=$1 AND "nid">$2 ORDER BY "nid" DESC';
+ $sqlarr = array($uid, intval($ret->rsv));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $nids = array();
+ while($it=pg_fetch_array($sqlr))
+ {
+ $nids[] = $it[0];
+ }
+ $sqlstr = 'SELECT * FROM "notice" WHERE "nid" IN ('.join($nids, ",").') ORDER BY "tim";';
+ $sqlr = pg_query($sqlc, $sqlstr);
+ $buf = array();
+ while($it = pg_fetch_object($sqlr))
+ {
+ $it->nid = intval($it->nid);
+ $it->typ = intval($it->typ);
+ $buf[] = $it;
+ }
+ pg_free_result($sqlr);
+ $sqlstr = 'UPDATE "notice_cache" SET "cnt"=0, "rsv"=$2 WHERE "uid"=$1;';
+ $sqlarr = array($uid, $nids[0]);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ return $buf;
+ }
+ else if($typ == NOTICE_ACT_OLD)
+ {
+ if($arg2 <= 0)
+ {
+ $arg2 = 1;
+ }
+ if($arg2 > NOTICE_MAX_LIM)
+ {
+ $arg2 = NOTICE_MAX_LIM;
+ }
+ $sqlstr = 'SELECT "nid" FROM "user_notice" WHERE "uid"=$1 AND "nid"<$2 ORDER BY "nid" DESC LIMIT $3';
+ $sqlarr = array($uid, $arg1, $arg2);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $nids = array();
+ while($it=pg_fetch_array($sqlr))
+ {
+ $nids[] = $it[0];
+ }
+ $sqlstr = 'SELECT * FROM "notice" WHERE "nid" IN ('.join($nids, ",").') ORDER BY "tim";';
+ $sqlr = pg_query($sqlc, $sqlstr);
+ $buf = array();
+ while($it = pg_fetch_object($sqlr))
+ {
+ $it->nid = intval($it->nid);
+ $it->typ = intval($it->typ);
+ $buf[] = $it;
+ }
+ pg_free_result($sqlr);
+ return $buf;
+ }
+ return false;
+ }
+
+ public static function clr($sqlc, $uid, $lim=NOTICE_DEF_LIM)
+ {
+ return false;
+ if($lim < 0)
+ {
+ $lim = 0;
+ }
+ $ret = self::check_new($sqlc, $uid);
+ $buf = preg_split("/[,]/", $ret->tmp);
+ $buf = array_slice($buf, 0, $ret->cnt+$lim);
+ $sqlstr = 'UPDATE "notice_cache" SET "tmp"=$1 WHERE "uid"=$2;';
+ $sqlarr = array(join($buf, ","), $uid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if($sqlr)
+ {
+ return count($buf);
+ }
+ return false;
+ }
+
+ // you can add notice by calling it.
+ public static function add($sqlc, $typ, $val, $txt)
+ {
+ if(!is_string($val))
+ {
+ $val = json_encode($val);
+ }
+ $sqlstr = 'INSERT INTO "notice" ("typ", "val", "txt", "tim") VALUES ($1, $2, $3, $4) RETURNING *;';
+ $sqlarr = array($typ, $val, $txt, date('Y-m-d H:i:s'));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ if($ret === false)
+ {
+ return false;
+ }
+ return json_encode($ret);
+ }
+
+ public static function del($sqlc, $cond)
+ {
+ $sqlstr = 'DELETE FROM "notice" WHERE 0';
+ if(isset($cond['nid']))
+ {
+ $sqlstr .= ' OR "nid"=$1';
+ }
+ if(isset($cond['tim']))
+ {
+ $sqlstr .= ' OR "tim" >= $2';
+ }
+ $sqlarr = array($cond['nid'], $cond['tim']);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)
+ {
+ return false;
+ }
+ return true;
+ }
+}
+?>
diff --git a/toj/php/notice.php b/toj/php/notice.php
new file mode 100644
index 0000000..a0f984a
--- /dev/null
+++ b/toj/php/notice.php
@@ -0,0 +1,110 @@
+<?php
+//ini_set("display_errors", "On");
+//error_reporting(E_ALL & ~E_NOTICE);
+
+require_once('notice.inc.php');
+
+/* usage:
+ * action count(uid): update notice count of uid, return value: integer
+ * action get(uid): update notice of uid, return notice data limited to notice count,
+ * and clear notice count. format: object array, see table "notice"
+ * action clear(uid, [limit]): clear cache number to notice_count+limit,
+ * does not affect notice, only user cache. return remain number as int.
+ * action add(type, value, context): add a notice, need admin permission now.
+ * **attention**: this is only for web, use notice::add with your own code,
+ * that function does not require any user permission.
+ * type is an integer, see "notice.inc.php" NOTICE_TYP_*.
+ * value are paired with type, like proid, sqid, uid, .., meaning nothing
+ * with NOTICE_TYP_ALL, but cannot be NULL.
+ * context is what you want. treat as string data so its format
+ * depends on your own.
+ * return 'S' when success.
+ */
+
+$sqlc = db_connect();
+$action = $_POST['action'];
+$data = json_decode($_POST['data']);
+
+if(strlen($action) == 0)
+{
+ die('Eno_action');
+}
+if(!sec_is_login())
+{
+ die('Eno_login');
+}
+$uid = intval($_COOKIE['uid']);
+$usr = user::get_from_uid($sqlc, $uid);
+if(!$usr)
+{
+ die('Eno_such_user');
+}
+
+if($action == 'count')
+{
+ $cnt = notice::get($sqlc, $uid, NOTICE_ACT_CNT);
+ echo $cnt;
+}
+else if($action == 'get')
+{
+ $nid = intval($data->nid);
+ if($nid > 0)
+ {
+ $cnt = intval($data->count);
+ $res = notice::get($sqlc, $uid, NOTICE_ACT_OLD, $nid, $cnt);
+ if($res === false)
+ {
+ die('Eno_such_nid');
+ }
+ echo json_encode($res);
+ }
+ else
+ {
+ $res = notice::get($sqlc, $uid, NOTICE_ACT_NEW);
+ echo json_encode($res);
+ }
+}
+else if($action == 'clear')
+{
+ $lim = NOTICE_DEF_LIM;
+ if(isset($data->limit))
+ {
+ $lim = intval($data->limit);
+ }
+ if($lim > NOTICE_MAX_LIM)
+ {
+ $lim = NOTICE_MAX_LIM;
+ }
+ $ret = notice::clr($sqlc, $uid, $lim);
+ echo $ret;
+}
+else if($action == 'add')
+{
+ if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) && $uid != 111)
+ //if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN))
+ {
+ die('Epermission_denied');
+ }
+ if(!isset($data->type))
+ {
+ die('Etype_is_empty');
+ }
+ if(!isset($data->value))
+ {
+ die('Evalue_is_empty');
+ }
+ if(!isset($data->context))
+ {
+ die('Econtext_is_empty');
+ }
+ $res = notice::add($sqlc, $data->type, $data->value, $data->context);
+ if(!$res)
+ {
+ die('Efail');
+ }
+ echo 'S';
+}
+
+db_close($sqlc);
+
+?>
diff --git a/toj/php/problem.inc.php b/toj/php/problem.inc.php
new file mode 100644
index 0000000..e41e633
--- /dev/null
+++ b/toj/php/problem.inc.php
@@ -0,0 +1,252 @@
+<?php
+require_once('common.inc.php');
+require_once('user.inc.php');
+require_once('square.inc.php');
+
+const PRONAME_LEN_MAX = 100;
+
+const CODE_LEN_MIN = 1;
+const CODE_LEN_MAX = 102400;
+
+const SUBMIT_MIN_INTERVAL = 10;
+
+$LANGUAGE = array(0x1=>'C/C++', 0x2=>'JAVA', 0x4=>'Pascal');
+$EXTENSION = array(0x1=>'cpp', 0x2=>'java', 0x4=>'pas');
+
+class problem
+{
+ public $proid;
+ public $modid;
+ public $proname;
+ public $hidden;
+
+ public static function getmod($sqlc, $modid)
+ {
+ //return pmodname, smodname, jmodname for specified $modid.
+ //False if not found.
+ $result = pg_query_params($sqlc, 'SELECT * FROM "mod" WHERE "modid"=$1 LIMIT 1;', array($modid));
+ $mret = pg_fetch_object($result);
+ pg_free_result($result);
+ if(!$mret)
+ return false;
+ return $mret;
+ }
+ public static function get($sqlc, $proid)
+ {
+ //return problem data: proid, modid, proname, pmodname, smodname, jmodname
+ //False if not found.
+ $result = pg_query_params($sqlc, 'SELECT * FROM "problem" WHERE "proid"=$1 LIMIT 1;', array(intval($proid))) or die ("Eerror_get_problem");
+ $ret = pg_fetch_object($result, null, 'problem');
+ pg_free_result($result);
+ if(!$ret)
+ return false;
+
+ $ret->proid = intval($ret->proid);
+ $ret->modid = intval($ret->modid);
+ $ret->admin_uid = intval($ret->admin_uid);
+
+ $mret = problem::getmod($sqlc, $ret->modid);
+ if(!$mret)
+ return false;
+
+ $ret->pmodname = $mret->pmodname;
+ $ret->smodname = $mret->smodname;
+ $ret->jmodname = $mret->jmodname;
+
+ return $ret;
+ }
+
+ public static function is_available($sqlc, $proid, $uid = null)
+ {
+ //return whether the problem is available for user $_COOKIE['uid'] or not.
+ //USER_PER_PROADMIN always OK
+ //admin of problem always OK
+ //if HIDDEN , then NOT OK except admins
+ //in sqid=1 always OK , even if not login
+ //otherwise must exist at least one common square with relationship >= SQUARE_USER_ACTIVE
+ $uidnull = false;
+ if($uid == null)
+ {
+ $uid = intval($_COOKIE['uid']);
+ $uidnull = true;
+ }
+ $sqlr = pg_query_params('SELECT "hidden", "admin_uid" FROM "problem" WHERE "proid"=$1;', array($proid));
+ $obj = pg_fetch_object($sqlr);
+ $hdn = $obj->hidden;
+ if($hdn == null)
+ return false; // no such problem
+
+ if(sec_check_level($sqlc, USER_PER_PROADMIN, $uidnull?null:$uid))
+ return true;
+
+ if((!$uidnull || sec_is_login()) && $uid == intval($obj->admin_uid))
+ return true;
+
+ if($hdn == "t")
+ return false;
+
+ $sqlstr = 'SELECT COUNT(*) FROM "pro_sq" WHERE "proid"=$1 AND "sqid"=$2;';
+ $sqlarr = array($proid, 1);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $ret = intval(pg_fetch_result($sqlr, 0));
+ if($ret > 0)
+ return true;
+
+ if($uidnull && !sec_is_login())
+ return false;
+
+ $sqlstr = 'SELECT COUNT("pro_sq"."sqid") FROM "pro_sq" INNER JOIN "us_sq" ON "pro_sq"."sqid"="us_sq"."sqid" WHERE "pro_sq"."proid"=$1 AND "us_sq"."uid"=$2 AND "us_sq"."relationship">=$3;';
+ $sqlarr = array($proid, $uid, SQUARE_USER_ACTIVE);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $ret = intval(pg_fetch_result($sqlr, 0));
+ if($ret > 0)
+ return true;
+
+ return false;
+ }
+
+ public static function submit($sqlc, $proid, $uid, $lang, $code)
+ {
+ //Submit code(or data) : $proid, $uid, $lang, $code
+ //Return subid. False if failed.
+
+ ////$submit_time = date('Y-m-d H:i:s');
+ ////$last_update = $submit_time;
+ $sqlstr = 'INSERT INTO "submit" ("proid", "uid", "lang") VALUES ($1, $2, $3) RETURNING subid;';
+ $sqlarr = array($proid, $uid, $lang);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $subid = intval(pg_fetch_result($sqlr, 0));
+ if(!$subid)
+ return false;
+
+ global $EXTENSION;
+ $ext = $EXTENSION[intval($lang)];
+ if($ext == null)
+ die('Ewrong_extension');
+
+ $parnum = $subid - ($subid%1000);
+ $pardir = '../center/submit/'.$parnum.'/';
+ if(!is_dir($pardir))
+ mkdir($pardir, 0755) or die('Ecannot_mkdir');
+ mkdir($pardir.$subid, 0755) or die('Ecannot_mkdir');
+ mkdir($pardir.$subid.'/data', 0755) or die('Ecannot_mkdir');
+ mkdir($pardir.$subid.'/result', 0755) or die('Ecannot_mkdir');
+
+ //$file = fopen($pardir.$subid.'/data/'.$subid.'.'.$ext,'w');
+ //20130205 tmp change
+ $file = fopen($pardir.$subid.'/data/main.'.$ext,'w');
+ if(!$file)
+ die('Ewrite_file_failed');
+ fwrite($file, $code);
+ fclose($file);
+
+ return $subid;
+ }
+
+ public static function add($sqlc, $pro)
+ {
+ //Add a new problem $pro into problem table.
+ //Return the inserted object. False if failed.
+
+ $sqlstr = 'INSERT INTO "problem" ("modid", "proname", "hidden", "admin_uid") VALUES ($1, $2, $3, $4) RETURNING *;';
+ $sqlarr = array($pro->modid, $pro->proname, $pro->hidden, $pro->admin_uid);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ if(!$sqlr)
+ return false;
+ $obj = pg_fetch_object($sqlr, null, 'problem');
+ pg_free_result($sqlr);
+ if(!$obj)
+ return false;
+
+ $obj->proid = intval($obj->proid);
+ $obj->modid = intval($obj->modid);
+ $obj->admin_uid = intval($obj->admin_uid);
+
+ return $obj;
+ }
+
+ public static function mod_get_lang($sqlc, $modid)
+ {
+ //get available language code (OR) format
+ //return language code
+
+ $sqlstr = 'SELECT "lang" FROM "mod" WHERE "modid"=$1;';
+ $sqlarr = array($modid);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ pg_free_result($sqlr);
+ if(!$ret)
+ return false;
+ return intval($ret);
+ }
+
+ public static function recent_submit($sqlc, $uid, $time)
+ {
+ //return submission number in recent $time seconds.
+ $lasttime = date('Y-m-d H:i:s', time()-$time);
+ $sqlstr = 'SELECT COUNT(*) FROM "submit" WHERE "uid"=$1 AND "submit_time" >= $2;';
+ $sqlarr = array($uid, $lasttime);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ if(!$ret)
+ return false;
+ return intval($ret);
+ }
+
+ public static function send_socket($subid, $proid)
+ {
+ ///send socket to center.
+ //Return true if success, false if failed.
+
+ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ $sconn = socket_connect($socket, '127.0.0.1', CENTER_SOCKET_PORT);
+
+ if(!$sconn)
+ return false;
+
+ $wret = socket_write($socket, $subid.chr(0).'{}'.chr(0));
+ if($wret === false)
+ return false;
+
+
+ $cret = socket_read($socket, 1024);
+ if($cret === false)
+ return false;
+ if($cret[0] != 'S')
+ return false;
+ return true;
+ }
+
+ public static function get_pro_stat($sqlc, $proid, $uid)
+ {
+ //get $uid 's score and is_ac of problem $proid.
+
+ $ret = new stdClass();
+
+ $sqlstr = 'SELECT COUNT(*) FROM "submit" WHERE "proid"=$1 AND "uid"=$2 AND "result"=0;';
+ $sqlarr = array($proid, $uid);
+ $res = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $acct = pg_fetch_result($res, 0);
+ $ret->is_ac = ($acct > 0);
+
+ $sqlstr = 'SELECT "score" FROM "submit" WHERE "proid"=$1 AND "uid"=$2 ORDER BY "score" DESC LIMIT 1;';
+ $sqlarr = array($proid, $uid);
+ $res = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $score = pg_fetch_result($res, 0);
+ if($score === false)
+ {
+ $ret->tried = false;
+ $ret->score = 0;
+ }
+ else
+ {
+ $ret->tried = true;
+ $ret->score = $score;
+ }
+
+ return $ret;
+ }
+}
+
+
+?>
diff --git a/toj/php/problem.php b/toj/php/problem.php
new file mode 100644
index 0000000..be79ecb
--- /dev/null
+++ b/toj/php/problem.php
@@ -0,0 +1,140 @@
+<?php
+ini_set("display_errors", "On");
+error_reporting(E_ALL & ~E_NOTICE);
+
+require_once('problem.inc.php');
+require_once('user.inc.php');
+
+$sqlc = db_connect();
+
+$action = $_POST['action'];
+$data = $_POST['data'];
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == 'get_pro')
+{
+ //get problem data: proid, modid, name, pmodname, smodname, jmodname
+ //only USER_LEVEL_SUPERADMIN or is_available
+ //data : proid
+
+ $dt = json_decode($data);
+
+ $proid = intval($dt->proid);
+
+ $ret = problem::get($sqlc, $proid);
+ if(!$ret)
+ die('Eget_problem');
+
+ if(!problem::is_available($sqlc, $proid))
+ die('Epermission_denied');
+
+ unset($ret->proid);
+ //unset($ret->hidden);
+
+ echo(json_encode($ret));
+}
+if($action == 'add_pro')
+{
+ //Add problem
+ //need SUPERADMIN
+ //data: modid, proname, [hidden]
+ if(!sec_is_login())
+ die('Enot_login');
+ if(!sec_check_level($sqlc, USER_PER_PROCREATOR))
+ die('Epermission_denied');
+
+ $dt = json_decode($data);
+
+ if(strlen($dt->proname) == 0)
+ die('Eproname_too_short');
+ if(strlen($dt->proname) > PRONAME_LEN_MAX)
+ die('Eproname_too_long');
+
+ if(!problem::getmod($sqlc, $dt->modid))
+ die('Ewrong_modid');
+
+ if($dt->hidden != 't' && $dt->hidden != 'f')
+ die('Ewrong_hidden_value');
+
+ /*CHECK OTHER DATA, TESTDATA ETC*/
+
+ $dt->admin_uid = intval($_COOKIE['uid']);
+
+ $pro = problem::add($sqlc, $dt);
+ if(!$pro)
+ die('Eadd_problem');
+
+ echo(json_encode($pro));
+}
+if($action == 'submit_code')
+{
+ //Submit code
+ //Need problem available
+ //data: proid, lang, code
+ if(!sec_is_login())
+ die('Enot_login');
+
+ $uid = intval($_COOKIE['uid']);
+ $dt = json_decode($data);
+
+ $proid = intval($dt->proid);
+
+ if(!problem::is_available($sqlc, $proid)){
+ die('Epermission_denied');
+ }
+
+ $obj = problem::get($sqlc, $proid);
+ $lang = intval($dt->lang);
+ $oklang = problem::mod_get_lang($sqlc, $obj->modid);
+ if($LANGUAGE[$lang] == null || (($lang & $oklang) == 0))
+ die('Ewrong_language');
+
+ if(strlen($dt->code) < CODE_LEN_MIN)
+ die('Ecode_too_short');
+ if(strlen($dt->code) > CODE_LEN_MAX)
+ die('Ecode_too_long');
+
+ //if(problem::recent_submit($sqlc, $uid, SUBMIT_MIN_INTERVAL) > 0)
+ // die('Esubmit_too_frequently');
+
+ $subid = problem::submit($sqlc, $proid, $uid, $lang, $dt->code);
+ if(!$subid)
+ die('Esubmit_code_failed');
+
+ /*ASSOCIATED SQUARE : CALL SQUARE MODULE TO GET EXTRA JUDGE OPTION*/
+
+ if(!problem::send_socket($subid, $proid))
+ die('Esend_socket_failed');
+
+ echo(json_encode($subid));
+}
+if($action == 'get_pro_stat')
+{
+ //Get score and is_ac for specified proid.
+ //Need login and problem available.
+ //data : proid
+
+ if(!sec_is_login())
+ die('Enot_login');
+
+ $uid = intval($_COOKIE['uid']);
+ $dt = json_decode($data);
+
+ $proid = intval($dt->proid);
+
+ if(!problem::is_available($sqlc, $proid)){
+ die('Epermission_denied');
+ }
+
+ $ret = problem::get_pro_stat($sqlc, $proid, $uid);
+ if(!$ret)
+ die('Eerror_get_pro_stat');
+
+ echo(json_encode($ret));
+}
+
+db_close($sqlc);
+
+
+?>
diff --git a/toj/php/pzreadtest.php b/toj/php/pzreadtest.php
new file mode 100644
index 0000000..b67ae9e
--- /dev/null
+++ b/toj/php/pzreadtest.php
@@ -0,0 +1,9 @@
+<?php
+ require_once('notice.inc.php');
+
+ function center_result_event($uid,$msg){
+ $db = db_connect();
+ notice::add($db,NOTICE_TYP_USR,$uid,json_encode($msg));
+ db_close($db);
+ }
+?>
diff --git a/toj/php/sqlib.inc.php b/toj/php/sqlib.inc.php
new file mode 100644
index 0000000..154bcbd
--- /dev/null
+++ b/toj/php/sqlib.inc.php
@@ -0,0 +1,5 @@
+<?php
+
+ require_once('sqlib_scoreboard.inc.php');
+
+?>
diff --git a/toj/php/sqlib_scoreboard.inc.php b/toj/php/sqlib_scoreboard.inc.php
new file mode 100644
index 0000000..84a71ef
--- /dev/null
+++ b/toj/php/sqlib_scoreboard.inc.php
@@ -0,0 +1,239 @@
+<?php
+
+ /*
+ Square mod library : Scoreboard
+ 2013/02/10 By TOJTeam
+
+ Get scoreboard by rank :
+ sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time, $start_rank, $number)
+
+ Get scoreboard of specific user :
+ sqlib_scoreboard::get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time, $uid)
+
+ $sqlc : sql connection to database 'toj'
+ $msqlc : sql connection to database 'toj_mod'
+ $sqid : square id number
+ $sboard_id : scoreboard id number (of square)
+ $score_func : function to determine rank_score
+ $start_time : start timestamp
+ $end_time : end timestamp
+ $start_rank : display from which rank
+ $number : number to display
+ $uid : user id number
+
+ Parameter format of $score_func:
+ func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $tries);
+
+ */
+
+ require_once('common.inc.php');
+
+ class sqlib_scoreboard
+ {
+ public static function def_func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $tries)
+ {
+ return $best_score;
+ }
+
+ public static function get_last_update($msqlc, $sqid, $sboard_id)
+ {
+ $sqlstr = 'SELECT "last_update" FROM "sqlib_scoreboard_last_update" WHERE "sqid"=$1 AND "sboard_id"=$2;';
+ $sqlarr = array($sqid, $sboard_id);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_result($res, 0);
+ return $ret;
+ }
+
+ public static function set_last_update($msqlc, $sqid, $sboard_id, $new)
+ {
+ $now = date('Y-m-d H:i:s+08');
+ $sqlstr = 'UPDATE "sqlib_scoreboard_last_update" SET "last_update"=$3 WHERE "sqid"=$1 AND "sboard_id"=$2;';
+ if($new)
+ {
+ $sqlstr = 'INSERT INTO "sqlib_scoreboard_last_update" ("sqid", "sboard_id", "last_update") VALUES ($1, $2, $3);';
+ }
+ $sqlarr = array($sqid, $sboard_id, $now);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ }
+
+ public static function get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time = null, $end_time = null, $start_offset, $number, $uid = null)
+ {
+ if(!$start_time)$start_time = '1900-01-01 01:01:01+08';
+ if(!$end_time)$end_time = '2222-01-01- 01:01:01+08';
+ sqlib_scoreboard::update($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time);
+
+ //display
+ $sqlstr = 'SELECT "a1"."uid", "a1"."rank_score", COUNT(*) AS "rank" FROM "sqlib_scoreboard_main" "a1", "sqlib_scoreboard_main" "a2" WHERE "a1"."sqid"=$1 AND "a1"."sboard_id"=$2 AND "a2"."sqid"=$1 AND "a2"."sboard_id"=$2 AND ("a2"."rank_score">"a1"."rank_score" OR "a2"."uid"="a1"."uid") GROUP BY "a1"."uid", "a1"."rank_score" ORDER BY "a1"."rank_score" DESC, "a1"."uid" LIMIT $4 OFFSET $3;';
+ $sqlarr = array($sqid, $sboard_id, $start_offset-1, $number);
+ if($uid)
+ {
+ $sqlstr = 'SELECT "a1"."uid", "a1"."rank_score", COUNT(*) AS "rank" FROM "sqlib_scoreboard_main" "a1", "sqlib_scoreboard_main" "a2" WHERE "a1"."sqid"=$1 AND "a1"."sboard_id"=$2 AND "a1"."uid"=$3 AND "a2"."sqid"=$1 AND "a2"."sboard_id"=$2 AND ("a2"."rank_score">"a1"."rank_score" OR "a2"."uid"="a1"."uid") GROUP BY "a1"."uid", "a1"."rank_score";';
+ $sqlarr = array($sqid, $sboard_id, $uid);
+ }
+
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $arr = pg_fetch_all($res);
+
+ $ret_obj = array();
+ foreach($arr as $item)
+ {
+ $obj = new stdClass();
+ $obj->uid = intval($item['uid']);
+ $obj->rank_score = doubleval($item['rank_score']);
+ $obj->rank = intval($item['rank']);
+ $obj->problem = array();
+
+ $sqlstr = 'SELECT "proid", "best_score", "best_time", "is_ac", "ac_time", "tries_before_ac", "last_score", "last_status", "last_time", "tries", "rank_score" FROM "sqlib_scoreboard_pro" WHERE "sqid"=$1 AND "sboard_id"=$2 AND "uid"=$3;';
+ $sqlarr = array($sqid, $sboard_id, $obj->uid);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $data = pg_fetch_all($res);
+ foreach($data as $pro)
+ {
+ $pobj = new stdClass();
+ $pobj->proid = intval($pro['proid']); ///
+ $pobj->best_score = doubleval($pro['best_score']);
+ $pobj->best_time = $pro['best_time'];
+ $pobj->is_ac = ($pro['is_ac']=='t');
+ $pobj->ac_time = $pro['ac_time'];
+ $pobj->tries_before_ac = intval($pro['tries_before_ac']);
+ $pobj->last_score = doubleval($pro['last_score']);
+ $pobj->last_status = intval($pro['last_status']);
+ $pobj->last_time = $pro['last_time'];
+ $pobj->tries = intval($pro['tries']);
+ $pobj->rank_score = doubleval($pro['rank_score']);
+
+ $proid = intval($pro['proid']);
+ $obj->problem[$proid] = $pobj;
+ }
+ array_push($ret_obj, $obj);
+ }
+ return $ret_obj;
+ }
+
+ public static function get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time = null, $end_time = null, $uid)
+ {
+ return sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time, null, null, $uid);
+ }
+
+ public static function update($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time)
+ {
+ $last_update = sqlib_scoreboard::get_last_update($msqlc, $sqid, $sboard_id);
+ $last_update_time = strtotime($last_update);
+ if(!$last_update)$last_update_time = 0;
+ if($last_update_time <= time()-2)
+ {
+ sqlib_scoreboard::set_last_update($msqlc, $sqid, $sboard_id, !$last_update);
+ }
+ else return;
+ $last_update = date('Y-m-d H:i:s+08', $last_update_time);
+
+ //echo ('update!!'.$last_update.'<br>');
+ $sqlstr = 'SELECT DISTINCT "uid" FROM "submit" WHERE "last_update">=$4 AND "proid" IN (SELECT "proid" FROM "pro_sq" WHERE "sqid"=$1) AND "submit_time">=$2 AND "submit_time"<=$3;';
+ $sqlarr = array($sqid, $start_time, $end_time, $last_update);
+ $res = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $uid_list = pg_fetch_all_columns($res);
+ foreach($uid_list as $item)
+ {
+ //echo($item.', ');
+ $uid = intval($item);
+ sqlib_scoreboard::update_user($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time, $uid);
+ }
+ }
+
+ public static function update_user($sqlc, $msqlc, $sqid, $sboard_id, $score_func, $start_time, $end_time, $uid)
+ {
+ $sqlstr = 'SELECT "proid" FROM "pro_sq" WHERE "sqid"=$1;';
+ $sqlarr = array($sqid);
+ $res = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $proid_list = pg_fetch_all_columns($res, 0);
+
+ $total_rank_score = 0.0;
+ foreach($proid_list as $item)
+ {
+ $proid = intval($item);
+ $sqlstr = 'SELECT "result", "score", "submit_time" FROM "submit" WHERE "uid"=$1 AND "proid"=$2 AND "submit_time">=$3 AND "submit_time"<=$4 ORDER BY "submit_time";';
+ $sqlarr = array($uid, $proid, $start_time, $end_time);
+ $res = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $sub_list = pg_fetch_all($res);
+
+ $best_score = -1.0;
+ $best_time = '1900-01-01 01:01:01+08';
+
+ $is_ac = false;
+ $ac_time = null;
+ $tries_before_ac = 0;
+
+ $tries = count($sub_list);
+ $last_score = null;
+ $last_status = null;
+ $last_time = null;
+ if($sub_list)
+ {
+ $last_score = doubleval($sub_list[$tries-1]['score']);
+ $last_status = intval($sub_list[$tries-1]['result']);
+ $last_time = $sub_list[$tries-1]['submit_time'];
+
+ foreach($sub_list as $obj)
+ {
+ $score = doubleval($obj['score']);
+ $status = intval($obj['result']);
+ $stime = $obj['submit_time'];
+ if($score > $best_score)
+ {
+ $best_score = $score;
+ $best_time = $stime;
+ }
+ if(!$is_ac)
+ {
+ if($status == 0) // JUDGE_AC
+ {
+ $is_ac = true;
+ $ac_time = $stime;
+ }
+ else
+ {
+ $tries_before_ac += 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ $tries = 0;
+ $best_score = null;
+ $best_time = null;
+ }
+
+ if($score_func == null)$score_func = array('sqlib_scoreboard', 'def_func');
+ $rank_score = $score_func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $last_time, $tries);
+ $sqlstr = 'SELECT COUNT(*) FROM "sqlib_scoreboard_pro" WHERE "sqid"=$1 AND "sboard_id"=$3 AND "proid"=$2 AND "uid"=$4;';
+ $sqlarr = array($sqid, $proid, $sboard_id, $uid);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $cnt = intval(pg_fetch_result($res, 0));
+
+ $sqlstr = 'UPDATE "sqlib_scoreboard_pro" SET "best_score"=$5, "best_time"=$6, "is_ac"=$7, "ac_time"=$8, "tries_before_ac"=$9, "last_score"=$10, "last_status"=$11, "last_time"=$12, "tries"=$13, "rank_score"=$14 WHERE "sqid"=$1 AND "sboard_id"=$2 AND "proid"=$3 AND "uid"=$4;';
+ if($cnt==0)
+ {
+ $sqlstr = 'INSERT INTO "sqlib_scoreboard_pro" ("sqid", "sboard_id", "proid", "uid", "best_score", "best_time", "is_ac", "ac_time", "tries_before_ac", "last_score", "last_status", "last_time", "tries", "rank_score") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);';
+ }
+ $sqlarr = array($sqid, $sboard_id, $proid, $uid, $best_score, $best_time, $is_ac?'t':'f', $ac_time, $tries_before_ac, $last_score, $last_status, $last_time, $tries, $rank_score);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ //var_dump($sqlarr);
+ $total_rank_score += $rank_score;
+ }
+
+ $sqlstr = 'SELECT COUNT(*) FROM "sqlib_scoreboard_main" WHERE "sqid"=$1 AND "sboard_id"=$2 AND "uid"=$3;';
+ $sqlarr = array($sqid, $sboard_id, $uid);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $cnt = intval(pg_fetch_result($res, 0));
+
+ $sqlstr = 'UPDATE "sqlib_scoreboard_main" SET "rank_score"=$4 WHERE "sqid"=$1 AND "sboard_id"=$2 AND "uid"=$3;';
+ if($cnt == 0)
+ {
+ $sqlstr = 'INSERT INTO "sqlib_scoreboard_main" ("sqid", "sboard_id", "uid", "rank_score") VALUES ($1, $2, $3, $4);';
+ }
+ $sqlarr = array($sqid, $sboard_id, $uid, $total_rank_score);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ }
+ }
+?>
diff --git a/toj/php/square.inc.php b/toj/php/square.inc.php
new file mode 100644
index 0000000..784490d
--- /dev/null
+++ b/toj/php/square.inc.php
@@ -0,0 +1,229 @@
+<?php
+
+require_once('common.inc.php');
+require_once('user.inc.php');
+require_once('problem.inc.php');
+
+const SQUARE_USER_PENDING = 1;
+const SQUARE_USER_ACTIVE = 2;
+const SQUARE_USER_ADMIN = 3;
+
+const SQUARE_PUBLIC = 3;
+const SQUARE_AUTH = 2;
+const SQUARE_PRIVATE = 1;
+
+const SQUARE_NAME_LEN_MAX = 100;
+
+class square
+{
+ public $sqid;
+ public $publicity;
+ public $start_time;
+ public $end_time;
+ public $sqname;
+ public $sqmodname;
+
+ public static function get($sqlc, $sqid)
+ {
+ //get square object from sqid
+ //return the object found. False if no such record
+ $sqlr = pg_query_params($sqlc, 'SELECT * FROM "square" WHERE "sqid"=$1 LIMIT 1;', array($sqid));
+ $ret = pg_fetch_object($sqlr, null, 'square');
+ pg_free_result($sqlr);
+ if($ret)$ret->sqid = intval($ret->sqid);
+ return $ret;
+ }
+
+ public static function add($sqlc, $sq)
+ {
+ //add a square object
+ //required member of sq : publicity, start_time, end_time, sqname, sqmodname
+ //publicity : SQUARE_PUBLIC, SQUARE_AUTH, SQUARE_PRIVATE
+ //return the object . False if failed.
+ $sqlstr = 'INSERT INTO "square" ("publicity", "start_time", "end_time", "sqname", "sqmodname") VALUES ($1, $2, $3, $4, $5) RETURNING *;';
+ $sqlarr = array($sq->publicity, $sq->start_time, $sq->end_time, $sq->sqname, $sq->sqmodname);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr, null, 'square');
+ pg_free_result($sqlr);
+ if($ret)$ret->sqid = intval($ret->sqid);
+ return $ret;
+ }
+
+ public static function edit($sqlc, $sqid, $sq)
+ {
+ //edit exist square data
+ //required member of sq : publicity, start_time, end_time, sqname, sqmodname
+ //publicity : SQUARE_PUBLIC, SQUARE_AUTH, SQUARE_PRIVATE
+ //return edited object . False if failed.
+ //
+ //if puhlicity change SQUARE_AUTH => SQUARE_PUBLIC,
+ //set all SQUARE_USER_PENDING users to SQUARE_USER_ACTIVE.
+ $oldsq = square::get($sqlc, $sqid);
+ if($oldsq->publicity==SQUARE_AUTH && $sq->publicity==SQUARE_PUBLIC)
+ {
+ $sqlstr = 'UPDATE "us_sq" SET "relationship"=$1 WHERE "sqid"=$2 AND "relationship"=$3;';
+ $sqlarr = array(SQUARE_USER_ACTIVE, $sqid, SQUARE_USER_PENDING);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ }
+ $sqlstr = 'UPDATE "square" SET "publicity"=$1, "start_time"=$2, "end_time"=$3, "sqname"=$4, "sqmodname"=$5 WHERE "sqid"=$6 RETURNING *;';
+ $sqlarr = array($sq->publicity, $sq->start_time, $sq->end_time, $sq->sqname, $sq->sqmodname, $sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr, null, 'square');
+ pg_free_result($sqlr);
+ if($ret)$ret->sqid = intval($ret->sqid);
+ return $ret;
+ }
+
+ public static function del($sqlc, $sqid)
+ {
+ //Delete the square $sqid. Also delete the user-square relation involves this square.
+ //return false if failed.
+ $sqlstr = 'DELETE FROM "square" WHERE "sqid"=$1;';
+ $sqlstr2 = 'DELETE FROM "us_sq" WHERE "sqid"=$1;';
+ $sqlr = pg_query_params($sqlc, $sqlstr, array($sqid));
+ if(!$sqlr)return false;
+ $sqlr = pg_query_params($sqlc, $sqlstr2, array($sqid));
+ if(!$sqlr)return false;
+ else return true;
+ }
+
+ public static function add_user($sqlc, $uid, $sqid, $relationship)
+ {
+ //add user into user-square relation.
+ //return false if failed.
+ $sqlstr = 'INSERT INTO "us_sq" ("uid", "sqid", "relationship") VALUES ($1, $2, $3) RETURNING *;';
+ $sqlarr = array($uid, $sqid, $relationship);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ pg_free_result($sqlr);
+ if(!$ret)return false;
+ else return true;
+ }
+
+ public static function del_user($sqlc, $uid, $sqid)
+ {
+ //delete user from user-square relation.
+ //return false if failed.
+ $sqlstr = 'DELETE FROM "us_sq" WHERE "uid"=$1 AND "sqid"=$2;';
+ $sqlarr = array($uid, $sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)return false;
+ else return true;
+ }
+
+ public static function set_user_relationship($sqlc, $uid, $sqid, $relationship)
+ {
+ //update user relationship.
+ //relationship: SQUARE_USER_PENDING, SQUARE_USER_ACTIVE, SQUARE_USER_ADMIN
+ //return false if failed.
+ $sqlr = pg_query_params($sqlc, 'UPDATE "us_sq" SET "relationship"=$3 WHERE "uid"=$1 AND "sqid"=$2;', array($uid, $sqid, $relationship));
+ if(!$sqlr)return false;
+ else return true;
+ }
+
+ public static function get_user_relationship($sqlc, $uid, $sqid)
+ {
+ //get the relationship of uid,sqid from user-square relation.
+ //Return the relationship. SQUARE_USER_PENDING, SQUARE_USER_ACTIVE, SQUARE_USER_ADMIN
+ //return false if no record in the table;
+ $sqlr = pg_query_params($sqlc, 'SELECT "relationship" FROM "us_sq" WHERE "uid"=$1 AND "sqid"=$2;', array($uid, $sqid));
+ $ret = pg_fetch_result($sqlr, 0);
+ if(!$ret)return false;
+ else return intval($ret);
+ }
+
+ public static function get_available_sq($sqlc, $uid, $minpub)
+ {
+ //get all available square for given uid and publicity at least minpub. (not includes entered ones)
+ //Return array of object, which contains each sqid, start_time, end_time, publicity, sqname, sqmodname
+ //return empty array if no record in the table;
+ $sqlstr = 'SELECT "sqid", "start_time", "end_time", "publicity", "sqname", "sqmodname" FROM "square" WHERE "sqid" NOT IN (SELECT "sqid" FROM "us_sq" WHERE "uid"=$1) AND "publicity" >= $2 ORDER BY (CASE WHEN "square"."end_time" IS NULL THEN "square"."sqid" ELSE 0 END), "square"."start_time", "square"."sqid";';
+ $sqlarr = array($uid, $minpub);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = array();
+ while($row = pg_fetch_object($sqlr))
+ {
+ array_push($ret, $row);
+ }
+ return $ret;
+ }
+
+ public static function get_entered_sq($sqlc, $uid)
+ {
+ //gel all entered square for given uid.
+ //Return array of object, which contains each sqid, start_time, end_time, publicity, sqname, sqmodname, relationship
+ //return empty array if no record in the table;
+ $sqlstr = 'SELECT "square"."sqid", "square"."start_time", "square"."end_time", "square"."publicity", "square"."sqname", "square"."sqmodname", "us_sq"."relationship" FROM "us_sq" INNER JOIN "square" ON "us_sq"."sqid"="square"."sqid" WHERE "us_sq"."uid"=$1 ORDER BY (CASE WHEN "square"."end_time" IS NULL THEN "square"."sqid" ELSE 0 END), "square"."start_time", "square"."sqid";';
+ $sqlarr = array($uid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = array();
+ while($row = pg_fetch_object($sqlr))
+ {
+ array_push($ret, $row);
+ }
+ return $ret;
+ }
+
+ public static function del_pro($sqlc, $proid, $sqid)
+ {
+ //Delete $proid from square $sqid.
+ //Return true if success, false if failed.
+ $sqlstr = 'DELETE FROM "pro_sq" WHERE "proid"=$1 AND "sqid"=$2;';
+ $sqlarr = array($proid, $sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)
+ return false;
+ return true;
+ }
+
+ public static function add_pro($sqlc, $proid, $sqid)
+ {
+ //Add problem $proid into square $sqid.
+ //Return true if success, false if failed.
+ $sqlstr = 'INSERT INTO "pro_sq" ("proid", "sqid") VALUES ($1, $2) RETURNING *;';
+ $sqlarr = array($proid, $sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ if(!$ret)
+ return false;
+ return true;
+ }
+
+ public static function is_pro_in_sq($sqlc, $proid, $sqid)
+ {
+ //Return whether problem $proid is in square $sqid or not.
+ $sqlstr = 'SELECT COUNT(*) FROM "pro_sq" WHERE "proid"=$1 AND "sqid"=$2;';
+ $sqlarr = array($proid, $sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = intval(pg_fetch_result($sqlr, 0));
+ return $ret > 0;
+ }
+
+ public static function get_sqmod($sqlc, $sqid)
+ {
+ //Return the sqmodname of square $sqid.
+ $sqlstr = 'SELECT "sqmodname" FROM "square" WHERE "sqid"=$1;';
+ $sqlarr = array($sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ return $ret;
+ }
+
+ public static function get_pro_list($sqlc, $sqid)
+ {
+ //get problem list of square $sqid.
+ $sqlstr = 'SELECT "problem"."proid", "problem"."proname", "problem"."hidden" FROM "problem" INNER JOIN "pro_sq" ON "problem"."proid"="pro_sq"."proid" WHERE "pro_sq"."sqid"=$1 ORDER BY "problem"."proid";';
+ $sqlarr = array($sqid);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = array();
+ while($obj = pg_fetch_object($sqlr))
+ {
+ $obj->proid = intval($obj->proid);
+ $obj->hidden = ($obj->hidden=='t');
+ array_push($ret, $obj);
+ }
+ return $ret;
+ }
+}
+
+?>
diff --git a/toj/php/square.php b/toj/php/square.php
new file mode 100644
index 0000000..4880ab3
--- /dev/null
+++ b/toj/php/square.php
@@ -0,0 +1,350 @@
+<?php
+//ini_set("display_errors", "On");
+
+require_once('square.inc.php');
+
+$sqlc = db_connect();
+
+$action = $_POST['action'];
+$data = $_POST['data'];
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == 'add_sq')
+{
+ //Add new square. level USER_LEVEL_SUPERADMIN or above required.
+ //data: sqname, publicity, [start_time, end_time], sqmodname
+
+ $sq = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+ if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN))
+ die('Epermission_denied');
+
+ if($sq->publicity != SQUARE_PUBLIC && $sq->publicity != SQUARE_AUTH && $sq->publicity != SQUARE_PRIVATE)
+ die('Ewrong_publicity');
+
+ if(!($sq->start_time))
+ $sq->start_time = date('Y-m-d H:i:s');
+ if(!($sq->end_time))
+ $sq->start_time = null;
+ if(strlen($sq->sqname)==0)
+ die('Esqname_too_short');
+ if(strlen($sq->sqname)>SQUARE_NAME_LEN_MAX)
+ die('Esqname_too_long');
+ if(strlen($sq->sqmodname)==0)
+ die('Esqmodname_empty');
+
+ $res = square::add($sqlc, $sq);
+ if(!$res)
+ die('Eadd_sq_failed');
+
+ $res2 = square::add_user($sqlc, $_COOKIE['uid'], $res->sqid, SQUARE_USER_ADMIN);
+ if(!$res2)
+ die('Eadd_admin_failed');
+
+ echo('S');
+}
+if($action == 'delete_sq')
+{
+ //Delete exist square. level USER_LEVEL_SUPERADMIN or above required.
+ //data : sqid
+
+ $sq = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+ if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN))
+ die('Epermission_denied');
+
+ $sqid = intval($sq->sqid);
+ if(!square::get($sqlc, $sqid))
+ die('Eno_such_sq');
+
+ $res = square::del($sqlc, $sqid);
+ if(!$res)
+ die('Edelete_failed');
+
+ echo('S');
+}
+if($action == 'edit_sq')
+{
+ //edit exist square. level USER_LEVEL_SUPERADMIN / SQUARE_USER_ADMIN or above required.
+ //data: sqid, sqname, publicity, [start_time, end_time], sqmodname
+
+ $sq = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $sqid = intval($sq->sqid);
+ if(!square::get($sqlc, $sqid))
+ die('Eno_such_sq');
+
+ if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) && !(square::get_user_relationship($sqlc, $_COOKIE['uid'], $sqid)>=SQUARE_USER_ADMIN))
+ die('Epermission_denied');
+
+ if($sq->publicity != SQUARE_PUBLIC && $sq->publicity != SQUARE_AUTH && $sq->publicity != SQUARE_PRIVATE)
+ die('Ewrong_publicity');
+
+ if(!($sq->start_time) && $sq->end_time)
+ $sq->start_time = date('Y-m-d H:i:s');
+ if(strlen($sq->sqname)==0)
+ die('Esqname_too_short');
+ if(strlen($sq->sqname)>SQUARE_NAME_LEN_MAX)
+ die('Esqname_too_long');
+ if(strlen($sq->sqmodname)==0)
+ die('Esqmodname_empty');
+
+ $res = square::edit($sqlc, $sqid, $sq);
+ if(!$res)
+ die('Eedit_failed');
+
+ echo('S');
+}
+if($action == 'get_sq')
+{
+ //get exist square data
+ //data: sqid
+ $sq = json_decode($data);
+
+ $sqid = intval($sq->sqid);
+
+ $ret = square::get($sqlc, $sqid);
+ if(!$ret)
+ die('Eno_such_sq');
+
+ echo(json_encode($ret));
+}
+if($action == 'add_user')
+{
+ //add user to exist square
+ //data: uid, sqid
+ $dt = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($dt->uid);
+ $sqid = intval($dt->sqid);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $sq = square::get($sqlc, $sqid);
+ if(!$sq)
+ die('Eno_such_sq');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || (square::get_user_relationship($sqlc, $_COOKIE['uid'], $sqid)>=SQUARE_USER_ADMIN);
+
+ if($uid != intval($_COOKIE['uid']) && !$adm)
+ die('Epermission_denied');
+
+ $rela = SQUARE_USER_ACTIVE;
+ if(!$adm)
+ {
+ if($sq->publicity == SQUARE_AUTH)
+ $rela = SQUARE_USER_PENDING;
+ if($sq->publicity == SQUARE_PRIVATE)
+ die('Eprivate_square');
+ }
+
+ if(square::get_user_relationship($sqlc, $uid, $sqid))
+ die('Ealready_entered');
+
+ $ret = square::add_user($sqlc, $uid, $sqid, $rela);
+ if(!$ret)
+ die('Eadd_user_failed');
+
+ echo('S');
+}
+if($action == 'delete_user')
+{
+ //delete user from user-square relation
+ //data : uid, sqid
+ $dt = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($dt->uid);
+ $sqid = intval($dt->sqid);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $sq = square::get($sqlc, $sqid);
+ if(!$sq)
+ die('Eno_such_sq');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || (square::get_user_relationship($sqlc, $_COOKIE['uid'], $sqid)>=SQUARE_USER_ADMIN);
+
+ if($uid != intval($_COOKIE['uid']) && !$adm)
+ die('Epermission_denied');
+
+ if(!square::get_user_relationship($sqlc, $uid, $sqid))
+ die('Enot_entered');
+
+ $ret = square::del_user($sqlc, $uid, $sqid);
+ if(!$ret)
+ die('Edelete_user_failed');
+
+ echo('S');
+}
+if($action == 'edit_user_relationship')
+{
+ //edit user relationship.
+ //data: uid, sqid, relationship
+ $dt = json_decode($data);
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($dt->uid);
+ $sqid = intval($dt->sqid);
+ $rel = intval($dt->relationship);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $sq = square::get($sqlc, $sqid);
+ if(!$sq)
+ die('Eno_such_sq');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || (square::get_user_relationship($sqlc, $_COOKIE['uid'], $sqid)>=SQUARE_USER_ADMIN);
+
+ if(!$adm)
+ die('Epermission_denied');
+
+ if(!square::get_user_relationship($sqlc, $uid, $sqid))
+ die('Enot_entered');
+
+ if($rel!=SQUARE_USER_PENDING && $rel!=SQUARE_USER_ACTIVE && $rel!=SQUARE_USER_ADMIN)
+die('Ewrong_relationship');
+
+ $ret = square::set_user_relationship($sqlc, $uid, $sqid, $rel);
+ if(!$ret)
+ die('Eedit_user_relationship_failed');
+
+ echo('S');
+}
+if($action == 'get_available_sq')
+{
+ //get all available square data: sqid, start_time, end_time, publicity, sqname for given uid.
+ //only USER_LEVEL_SUPERADMIN can see SQUARE_PRIVATE squares.
+ //data: (no)
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($_COOKIE['uid']);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN);
+
+ $pub = 2;
+ if($adm)
+ $pub = 1;
+
+ $list = square::get_available_sq($sqlc, $uid, $pub);
+
+ $ret->list = $list;
+ $ret->timestamp = date('Y-m-d H:i:s');
+
+ echo(json_encode($ret));
+}
+if($action == 'get_entered_sq')
+{
+
+ //get all entered square data: sqid, start_time, end_time, publicity, sqname, relationship for given uid.
+ //data: (no)
+
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($_COOKIE['uid']);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $list = square::get_entered_sq($sqlc, $uid);
+
+ $ret->list = $list;
+ $ret->timestamp = date('Y-m-d H:i:s');
+
+ echo(json_encode($ret));
+}
+if($action == 'add_pro_into_sq')
+{
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($_COOKIE['uid']);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $dt = json_decode($data);
+ if(!problem::is_available($sqlc, $dt->proid))
+ die('Ewrong_proid');
+
+ if(!square::get($sqlc, $dt->sqid))
+ die('Ewrong_sqid');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || square::get_user_relationship($sqlc, $uid, $dt->sqid) >= SQUARE_USER_ADMIN;
+
+ if(!$adm)
+ die('Enot_square_admin');
+
+ if(square::is_pro_in_sq($sqlc, $dt->proid, $dt->sqid))
+ die('Ealready_in_square');
+
+ $ret = square::add_pro($sqlc, $dt->proid, $dt->sqid);
+ if(!$ret)
+ die('Eadd_problem_into_square_failed');
+
+ echo('S');
+}
+if($action == 'delete_pro_from_sq')
+{
+ if(!sec_is_login())
+ die('Eno_login');
+
+ $uid = intval($_COOKIE['uid']);
+
+ $usr = user::get_from_uid($sqlc, $uid);
+ if(!$usr)
+ die('Eno_such_user');
+
+ $dt = json_decode($data);
+
+ if(!square::get($sqlc, $dt->sqid))
+ die('Ewrong_sqid');
+
+ $adm = sec_check_level($sqlc, USER_LEVEL_SUPERADMIN) || square::get_user_relationship($sqlc, $uid, $dt->sqid) >= SQUARE_USER_ADMIN;
+
+ if(!$adm)
+ die('Enot_square_admin');
+
+ if(!square::is_pro_in_sq($sqlc, $dt->proid, $dt->sqid))
+ die('Enot_in_square');
+
+ $ret = square::del_pro($sqlc, $dt->proid, $dt->sqid);
+ if(!$ret)
+ die('Edelete_problem_from_square_failed');
+
+ echo('S');
+}
+
+db_close($sqlc);
+
+?>
diff --git a/toj/php/status.inc.php b/toj/php/status.inc.php
new file mode 100644
index 0000000..d9f4f7d
--- /dev/null
+++ b/toj/php/status.inc.php
@@ -0,0 +1,133 @@
+<?php
+require_once('common.inc.php');
+require_once('user.inc.php');
+require_once('problem.inc.php');
+
+const SUBMIT_COUNT_MAX = 100;
+const SUBMIT_SLEEP_TIME = 2;
+const SUBMIT_WAIT_MAX = 10;
+
+class status
+{
+ public static function get_submit($sqlc, $filter, $sort, $count, $last_update, $admin)
+ {
+ //get submit from submit table.
+ //return an array with every entry an object of submission.
+ $condstr = '';
+ $ordstr = '';
+
+ if($admin != true)
+ {
+ $uid = $_COOKIE['uid'];
+ if(!sec_is_login())
+ $uid = 0;
+ $condstr = $condstr.'("problem"."admin_uid"='.intval($uid).' OR "problem"."hidden"=\'f\') AND ';
+ }
+
+ if($last_update != null)
+ {
+ $condstr = $condstr.'"last_update">\''.pg_escape_string($last_update).'\' AND ';
+ }
+
+ if($filter->userid != null)
+ {
+ $condstr = $condstr.'"uid"='.pg_escape_string($filter->userid).' AND ';
+ }
+ if($filter->result != null)
+ {
+ $condstr = $condstr.'"result"='.pg_escape_string($filter->result).' AND ';
+ }
+ if($filter->proid != null)
+ {
+ $condstr = $condstr.'"proid"='.pg_escape_string($filter->proid).' AND ';
+ }
+ if($filter->lang != null)
+ {
+ $condstr = $condstr.'"lang"='.pg_escape_string($filter->lang).' AND ';
+ }
+ if($sort->score != null)
+ {
+ $relstr = $sort->score[0]==0 ? '<=' : '>=';
+ $condstr = $condstr.'"score"'.$relstr.pg_escape_string($sort->score[1]).' AND ';
+ $ordstr = $ordstr.'"score" '.($sort->score[0]==0 ? 'DESC' : 'ASC').' ,';
+ }
+ if($sort->runtime != null)
+ {
+ $relstr = $sort->runtime[0]==0 ? '<=' : '>=';
+ $condstr = $condstr.'"runtime"'.$relstr.pg_escape_string($sort->runtime[1]).' AND ';
+ $ordstr = $ordstr.'"runtime" '.($sort->runtime[0]==0 ? 'DESC' : 'ASC').' ,';
+ }
+ if($sort->maxmem != null)
+ {
+ $relstr = $sort->maxmem[0]==0 ? '<=' : '>=';
+ $condstr = $condstr.'"memory"'.$relstr.pg_escape_string($sort->maxmem[1]).' AND ';
+ $ordstr = $ordstr.'"memory" '.($sort->maxmem[0]==0 ? 'DESC' : 'ASC').' ,';
+ }
+ if($sort->subid != null)
+ {
+ $relstr = $sort->subid[0]==0 ? '<' : '>';
+ $condstr = $condstr.'"subid"'.$relstr.pg_escape_string($sort->subid[1]);
+ $ordstr = $ordstr.'"subid" '.($sort->subid[0]==0 ? 'DESC' : 'ASC');
+ }
+
+
+ $sqlstr = 'SELECT "submit".*, "user"."nickname" FROM ("submit" INNER JOIN "user" ON "submit"."uid"="user"."uid") INNER JOIN "problem" ON "submit"."proid"="problem"."proid" WHERE '.$condstr.' ORDER BY '.$ordstr.' LIMIT '.pg_escape_string($count).';';
+
+ //echo($sqlstr.'<br>');
+ $sqlr = pg_query($sqlc, $sqlstr);
+ //return pg_fetch_object($sqlr);
+ $ret = array();
+ while($obj = pg_fetch_object($sqlr))
+ {
+ $obj->subid = intval($obj->subid);
+ $obj->uid = intval($obj->uid);
+ $obj->proid = intval($obj->proid);
+ $obj->result = intval($obj->result);
+ $obj->runtime = intval($obj->runtime);
+ $obj->memory = intval($obj->memory);
+ $obj->score = intval($obj->score);
+ $obj->lang = intval($obj->lang);
+
+ array_push($ret, $obj);
+ }
+
+ return $ret;
+ }
+
+ public static function get_by_subid($sqlc, $subid)
+ {
+ //get submit information by subid.
+ //return submit information.
+
+ $sqlstr = 'SELECT "submit".*, "mod"."smodname" FROM ("submit" INNER JOIN "problem" ON "submit"."proid"="problem"."proid") INNER JOIN "mod" ON "problem"."modid"="mod"."modid" WHERE "subid"=$1;';
+ $sqlarr = array($subid);
+ $sqlr = pg_query_params($sqlstr, $sqlarr);
+ $ret = pg_fetch_object($sqlr);
+ if(!$ret)
+ die('Eno_such_subid');
+ $ret->subid = intval($ret->subid);
+ $ret->proid = intval($ret->proid);
+ $ret->uid = intval($ret->uid);
+ $ret->result = intval($ret->result);
+ $ret->memory = intval($ret->memory);
+ $ret->score = intval($ret->score);
+ $ret->lang = intval($ret->lang);
+
+ return $ret;
+ }
+
+ public static function subid_is_available($sqlc, $subid)
+ {
+ //decide whether subid is visible or not.
+ //Return true if OK, false if permission denied or failed.
+ $sub = status::get_by_subid($sqlc, $subid);
+ if(!$sub)
+ return false;
+ $ret = problem::is_available($sqlc, $sub->proid);
+ if(!$ret)
+ return false;
+ return true;
+ }
+}
+
+?>
diff --git a/toj/php/status.php b/toj/php/status.php
new file mode 100644
index 0000000..5c00580
--- /dev/null
+++ b/toj/php/status.php
@@ -0,0 +1,70 @@
+<?php
+ini_set("display_errors", "On");
+error_reporting(E_ALL & ~E_NOTICE);
+
+require_once('status.inc.php');
+
+$sqlc = db_connect();
+
+$action = $_POST['action'];
+$data = $_POST['data'];
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == 'get_submit')
+{
+ //get submit from submit table
+ //data: sort, sort->subid, count, [wait, filter, last_update]
+ $dt = json_decode($data);
+ if($dt->sort->subid == null)
+ die('Eno_sort_subid');
+ if($dt->count == null)
+ die('Eno_count');
+ $cnt = intval($dt->count);
+ if($cnt <= 0)
+ die('Etoo_few_count');
+ if($cnt > SUBMIT_COUNT_MAX)
+ die('Etoo_many_count');
+
+ $wait = intval($dt->wait);
+ if($wait > SUBMIT_WAIT_MAX)
+ die('Etoo_many_wait');
+
+ $nowwait = $wait;
+ $isadm = sec_check_level($sqlc, USER_PER_PROADMIN);
+
+ while(1)
+ {
+ $ret = status::get_submit($sqlc, $dt->filter, $dt->sort, $cnt, $dt->last_update, $isadm);
+ if($ret != null)
+ {
+ /* OUTPUT */
+ echo(json_encode($ret));
+ exit(0);
+ }
+ //die('Efail');
+ $nowwait--;
+ if($nowwait<0)break;
+ sleep(SUBMIT_SLEEP_TIME);
+ }
+ die('Eno_result');
+}
+if($action == 'get_by_subid')
+{
+ //get submission data and smodname by subid.
+ //problem must be available for the user.
+ //data: subid
+ $dt = json_decode($data);
+ $subid = intval($dt->subid);
+ if(!$subid)
+ die('Eno_subid');
+ $obj = status::get_by_subid($sqlc, $subid);
+
+ if(!problem::is_available($sqlc, $obj->proid))
+ die('Epermission_denied');
+
+ echo(json_encode($obj));
+}
+
+db_close($sqlc);
+?>
diff --git a/toj/php/step.inc.php b/toj/php/step.inc.php
new file mode 100644
index 0000000..a116a64
--- /dev/null
+++ b/toj/php/step.inc.php
@@ -0,0 +1,17 @@
+<?php
+
+require_once('common.inc.php');
+require_once('square.inc.php');
+require_once('sqlib_scoreboard.inc.php');
+
+function get_prob_stat_uid($sqlc, $msqlc, $sqid, $sboard_id, $uid)
+{
+ $sq = square::get($sqlc, $sqid);
+ if(!$sq)die('Eno_such_sq');
+
+ $data = sqlib_scoreboard::get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, null, $sq->start_time, $sq->end_time, $uid);
+
+ return $data[0];
+}
+
+?>
diff --git a/toj/php/step.php b/toj/php/step.php
new file mode 100644
index 0000000..6425ae1
--- /dev/null
+++ b/toj/php/step.php
@@ -0,0 +1,64 @@
+<?php
+//ini_set("display_errors", "On");
+
+require_once('common.inc.php');
+require_once('step.inc.php');
+require_once('teamt.php');
+
+$sqlc = db_connect();
+$msqlc = db_connect('toj_mod');
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == '')
+{
+}
+
+$uid = $_GET['uid'];
+$dat = get_prob_stat_uid($sqlc, $msqlc, 1, 2, $uid);
+
+//var_dump($dat);
+echo('uid : '.$dat->uid.'<br>');
+foreach($dat->problem as $prob)
+{
+ echo('problem '.$prob->proid.' : ');
+ if(!$prob->tries)
+ {
+ echo('--<br>');
+ continue;
+ }
+ echo($prob->best_score.' ');
+ if($prob->is_ac)echo('AC');
+ echo('<br>');
+}
+
+$term = 1;
+$teamid = get_teamid($msqlc, $term, $uid);
+echo('<br>Team : '.$teamid.'<br>Members : <br>');
+$members = get_team_member($msqlc, $term, $teamid);
+foreach($members as $mem)
+{
+ echo('<br>Uid : '.$mem->uid.' ( Level '.$mem->level.' )<br>');
+ $uid = intval($mem->uid);
+ if($uid == intval($_GET['uid']))continue;
+ $dat = get_prob_stat_uid($sqlc, $msqlc, 1, 2, $uid);
+
+ foreach($dat->problem as $prob)
+ {
+ echo('problem '.$prob->proid.' : ');
+ if(!$prob->tries)
+ {
+ echo('--<br>');
+ continue;
+ }
+ echo($prob->best_score.' ');
+ if($prob->is_ac)echo('AC');
+ echo('<br>');
+ }
+}
+
+
+db_close($sqlc);
+db_close($msqlc);
+
+?>
diff --git a/toj/php/teamt.php b/toj/php/teamt.php
new file mode 100644
index 0000000..ca1cd4b
--- /dev/null
+++ b/toj/php/teamt.php
@@ -0,0 +1,28 @@
+<?php
+
+require_once('common.inc.php');
+
+function get_teamid($msqlc, $term, $uid)
+{
+ $sqlstr = 'SELECT "teamid" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "uid"=$2;';
+ $sqlarr = array($term, $uid);
+ $res = pg_query_params($sqlstr, $sqlarr);
+ $teamid = pg_fetch_result($res, 0);
+ return $teamid;
+}
+
+function get_team_member($msqlc, $term, $teamid)
+{
+ $sqlstr = 'SELECT "uid", "level" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "teamid"=$2 ORDER BY "level" DESC, "uid";';
+ $sqlarr = array($term, $teamid);
+ $res = pg_query_params($sqlstr, $sqlarr);
+ $ret = array();
+ while($obj = pg_fetch_object($res))
+ {
+ array_push($ret, $obj);
+ }
+ return $ret;
+}
+
+
+?>
diff --git a/toj/php/test.php b/toj/php/test.php
new file mode 100644
index 0000000..a38a8a8
--- /dev/null
+++ b/toj/php/test.php
@@ -0,0 +1,32 @@
+<?php
+ini_set("display_errors", "On");
+error_reporting(E_ALL & ~E_NOTICE);
+
+require_once('common.inc.php');
+require_once('sqlib.inc.php');
+require_once('user.inc.php');
+
+$msqlc = db_connect('toj_mod');
+$sqlc = db_connect();
+
+function func($sqid, $proid, $best_score, $best_time, $is_ac, $ac_time, $tries_before_ac, $last_score, $last_status, $last_time, $tries)
+{
+ return $best_score;
+}
+
+//$a = intval($_GET['a']);
+//sqlib_scoreboard::set_last_update($msqlc, 1, 4, false);
+//$scb = sqlib_scoreboard::get_scoreboard($sqlc, $msqlc, 1, $a, func, null, null, 1, 20);
+//var_dump($scb);
+//echo(json_encode($scb));
+//$test = sqlib_scoreboard::get_last_update($msqlc, 1, $a);
+//echo($test.'<br>');
+//echo(strtotime($test).'<br>');
+//echo(time());
+
+$res = user::reset_password($sqlc, 130);
+var_dump($res);
+
+db_close($sqlc);
+db_close($msqlc);
+?>
diff --git a/toj/php/user.inc.php b/toj/php/user.inc.php
new file mode 100644
index 0000000..1a3eaef
--- /dev/null
+++ b/toj/php/user.inc.php
@@ -0,0 +1,212 @@
+<?php
+
+require_once('common.inc.php');
+require_once('/srv/http/phpmailer/class.phpmailer.php');
+
+const USERNAME_LEN_MIN = 5;
+const USERNAME_LEN_MAX = 20;
+const PASSWORD_LEN_MIN = 5;
+const PASSWORD_LEN_MAX = 32;
+const NICKNAME_LEN_MIN = 1;
+const NICKNAME_LEN_MAX = 32;
+const EMAIL_LEN_MAX = 100;
+
+const USER_PER_USER = 0x00000001;
+const USER_PER_PROCREATOR = 0x00000002;
+const USER_PER_PROADMIN = 0x00000004;
+
+const USER_LEVEL_USER = 0x00000001;
+const USER_LEVEL_PROCREATOR = 0x00000003;
+const USER_LEVEL_PROADMIN = 0x00000007;
+const USER_LEVEL_ADMIN = 0x0000ffff;
+const USER_LEVEL_SUPERADMIN = 0xffffffff;
+
+class user
+{
+ public $uid;
+ public $username;
+ public $password;
+ public $nickname;
+ public $aboutme;
+ public $avatar;
+ public $level;
+ public $email;
+
+ public static function get_from_uid($sqlc, $uid)
+ {
+ //return user object of specified uid. False if user doesn't exists.
+
+ $result = pg_query_params($sqlc, 'SELECT * FROM "user" WHERE "uid"=$1 LIMIT 1;', array(intval($uid))) or die ("Eerror_get_user");
+ $ret = pg_fetch_object($result, null, 'user');
+ pg_free_result($result);
+ if(!$ret)
+ return false;
+ $ret->uid = intval($ret->uid);
+ $ret->level = intval($ret->level);
+ return $ret;
+ }
+
+ public static function get_from_username($sqlc, $username)
+ {
+ //return user object of specified username. False if user doesn't exists.
+
+ $result = pg_query_params($sqlc, 'SELECT * FROM "user" WHERE "username"=$1 LIMIT 1;', array($username));
+ $ret = pg_fetch_object($result, null, 'user');
+ pg_free_result($result);
+ if(!$ret)
+ return false;
+ $ret->uid = intval($ret->uid);
+ $ret->level = intval($ret->level);
+
+ return $ret;
+ }
+
+ public static function add($sqlc, $user)
+ {
+ //add user to database , with $user the user data object
+ //return inserted user object. False if failed.
+ //Assume the insertion is valid!!
+ //requires member: string username, string nickname, string password, stirng aboutme, string avatar, string email
+
+ $sqlstr = 'INSERT INTO "user" ("username", "nickname", "password", "aboutme", "avatar", "email") VALUES ($1, $2, $3, $4, $5, $6) RETURNING *;';
+ $sqlarr = array($user->username, $user->nickname, $user->password, '', '', $user->email);
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)return false;
+ //$sqlr = pg_query($sqlc, 'SELECT SCOPE_IDENTITY();');
+ $obj = pg_fetch_object($sqlr, null, 'user');
+ pg_free_result($sqlr);
+ if($obj)$obj->uid = intval($obj->uid);
+ return $obj;
+ }
+
+ public static function update($sqlc, $user)
+ {
+ //update user data into database, with $user the user data object
+ //return updated object. False if failed.
+ //Assume the update is valid!!
+ //requires member: string nickname, string password, string aboutme, string avatar, string email, int uid
+
+ $sqlstr = 'UPDATE "user" SET "nickname"=$1, "password"=$2, "aboutme"=$3, "avatar"=$4, "email"=$5 WHERE "uid"=$6 RETURNING *;';
+ $sqlarr = array($user->nickname, $user->password, $user->aboutme, $user->avatar, $user->email, intval($user->uid));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)return false;
+ $obj = pg_fetch_object($sqlr, null, 'user');
+ pg_free_result($sqlr);
+ if($obj)$obj->uid = intval($obj->uid);
+ return $obj;
+ }
+
+ /*public static function update_property($sqlc, $user)
+ {
+ //update property of given user.
+ //return updated object. False if failed.
+ //Assume the update is valid!!
+ //requires member: int[] property, int uid;
+
+ $sqlstr = 'UPDATE "user" SET "property"=$1 WHERE "uid"=$2 RETURNING *;';
+ $sqlarr = array($user->property, intval($user->uid));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ if(!$sqlr)return false;
+ $obj = pg_fetch_object($sqlr, null, 'user');
+ pg_free_result($sqlr);
+ if($obj)$obj->uid = intval($obj->uid);
+ return $obj;
+ }*/
+
+ public static function get_username($sqlc, $uid)
+ {
+ //return username of given uid. False if not found.
+
+ $sqlstr = 'SELECT "username" FROM "user" WHERE "uid"=$1 LIMIT 1;';
+ $sqlarr = array(intval($uid));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ pg_free_result($sqlr);
+ return $ret;
+ }
+
+ public static function get_nickname($sqlc, $uid)
+ {
+ //return nickname of given uid. False if not found.
+
+ $sqlstr = 'SELECT "nickname" FROM "user" WHERE "uid"=$1 LIMIT 1;';
+ $sqlarr = array(intval($uid));
+ $sqlr = pg_query_params($sqlc, $sqlstr, $sqlarr);
+ $ret = pg_fetch_result($sqlr, 0);
+ pg_free_result($sqlr);
+ return $ret;
+ }
+
+ public static function reset_password($sqlc, $uid)
+ {
+ //reset password for given uid. False if not found.
+
+ $user = user::get_from_uid($sqlc, $uid);
+ if(!$user)return false;
+ $email = $user->email;
+ if(!$email)return false;
+
+ $passlen = 8;
+ $newpass = '';
+ for($i = 0; $i < $passlen; $i++)
+ {
+ $v = rand()%62;
+ $c = null;
+ if($v<10)$c = chr(48 + $v);
+ else if($v<36)$c = chr(65 + $v - 10);
+ else $c = chr(97 + $v - 36);
+ $newpass = $newpass.$c;
+ }
+ echo($newpass.'<br>');
+
+ //email
+
+ $cmail = new PHPMailer();
+ $cmail->IsSMTP();
+
+ $cmail->SMTPAuth = true;
+ $cmail->SMTPSecure = 'SSL';
+ $cmail->Host = 'ssl://'.SMTP_HOST;
+ $cmail->Port = 465;
+ $cmail->Username = SMTP_USER;
+ $cmail->Password = SMTP_PASS;
+ $cmail->From = 'sprout@csie.ntu.edu.tw';
+ $cmail->FromName = 'Taiwan Online Judge';
+
+ $cmail->AddAddress($email, $user->nickname);
+ $cmail->WordWrap = 70;
+ $cmail->Subject = 'TOJ Password Reset Notice';
+ $cmail->IsHTML = true;
+ $cmail->Body = 'Hi '.$user->nickname.' ('.$user->username.') , your new password is '.$newpass.' .';
+ if(!$cmail->Send())
+ {
+ echo($cmail->ErrorInfo.'<br>');
+ return false;
+ }
+
+
+ return true;
+
+ $user->password = hash('sha512', $newpass);
+ $nuser = user::update($sqlc, $user);
+ if(!$nuser)return false;
+
+ return true;
+ }
+}
+
+function sec_check_level($sqlc, $lv, $uid = null)
+{
+ $uidnull = false;
+ if($uid == null)
+ {
+ $uid = intval($_COOKIE['uid']);
+ $uidnull = true;
+ }
+ if($uidnull && !sec_is_login())
+ return false;
+ $user = user::get_from_uid($sqlc, $uid);
+ return (($user->level & $lv) == $lv);
+}
+
+?>
diff --git a/toj/php/user.php b/toj/php/user.php
new file mode 100644
index 0000000..4570700
--- /dev/null
+++ b/toj/php/user.php
@@ -0,0 +1,160 @@
+<?php
+//ini_set("display_errors", "On");
+//error_reporting(E_ALL & ~E_NOTICE);
+
+require_once('user.inc.php');
+
+$sqlc = db_connect();
+
+$action = $_POST['action'];
+$data = $_POST['data'];
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == 'register')
+{
+ //Add new user.
+ //Data: username, password, nickname, email, [aboutme, avatar]
+
+ $user = json_decode($data);
+
+ if(strlen($user->username)<USERNAME_LEN_MIN)
+ die('Eusername_too_short');
+ if(strlen($user->username)>USERNAME_LEN_MAX)
+ die('Eusername_too_long');
+ if(strlen($user->password)<PASSWORD_LEN_MIN)
+ die('Epassword_too_short');
+ if(strlen($user->password)>PASSWORD_LEN_MAX)
+ die('Epassword_too_long');
+ if(strlen($user->nickname)<NICKNAME_LEN_MIN)
+ die('Enickname_too_short');
+ if(strlen($user->nickname)>NICKNAME_LEN_MAX)
+ die('Enickname_too_long');
+ if(strlen($user->email)==0)
+ die('Eempty_email');
+ if(strlen($user->email)>EMAIL_LEN_MAX)
+ die('Eemail_too_long');
+ //if($user->password != $user->passconf)
+ // die('Epassword_not_match');
+
+ if(user::get_from_username($sqlc, $user->username) != false)
+ die('Eusername_exists');
+
+ $user->password = hash('sha512', $user->password);
+
+ $res = user::add($sqlc, $user);
+
+ if(!$res)
+ die('Einsert_failed');
+
+ setcookie('uid', $res->uid, time() + 31536000, '/toj/');
+ setcookie('usec', hash('sha512', $res->uid.SEC_SALT), time() + 31536000, '/toj/');
+
+ echo('S');
+}
+if($action == 'update')
+{
+ //Update exist user
+ //data: nickname, [aboutme, avatar], [oldpw, password]
+
+ $user = json_decode($data);
+
+ if(!sec_is_login())
+ die('Enot_login');
+
+ $user->uid = $_COOKIE['uid'];
+
+ $olduser = user::get_from_uid($sqlc, $user->uid);
+ if(!$olduser)
+ die('Eget_user_failed');
+
+ if(strlen($user->oldpw)>0)
+ {
+ if(strlen($user->password)<PASSWORD_LEN_MIN)
+ die('Epassword_too_short');
+ if(strlen($user->password)>PASSWORD_LEN_MAX)
+ die('Epassword_too_long');
+ //if($user->password != $user->passconf)
+ // die('Epassword_not_match');
+
+ $oldhash = hash('sha512', $user->oldpw);
+
+ if($olduser->password != $oldhash)
+ die('Eold_password_not_match');
+
+ $user->password = hash('sha512', $user->password);
+ }
+ else
+ {
+ $user->password = $olduser->password;
+ }
+
+ if(strlen($user->nickname)<NICKNAME_LEN_MIN)
+ die('Enickname_too_short');
+ if(strlen($user->nickname)>NICKNAME_LEN_MAX)
+ die('Enickname_too_long');
+ if(strlen($user->email)==0)
+ die('Eempty_email');
+ if(strlen($user->email)>EMAIL_LEN_MAX)
+ die('Eemail_too_long');
+
+ $res = user::update($sqlc, $user);
+ if(!$res)
+ die('Eupdate_failed');
+
+ echo('S');
+}
+if($action == 'view')
+{
+ //View user data
+ //data: uid
+
+ $cls = json_decode($data);
+
+ if($cls->uid == null)
+ {
+ if(!sec_is_login())
+ die('Enot_login_or_please_set_uid');
+ $cls->uid = intval($_COOKIE['uid']);
+ }
+ $user = user::get_from_uid($sqlc, $cls->uid);
+ if(!$user)
+ die('Eget_user_failed');
+
+ unset($user->password);
+ if(intval($_COOKIE['uid']) != $user->uid)
+ unset($user->email);
+
+ echo(json_encode($user));
+}
+if($action == 'login')
+{
+ //Login.
+ //data: username, password
+ $login = json_decode($data);
+
+ if(strlen($login->username)==0)
+ die('Eno_username');
+ if(strlen($login->username)>USERNAME_LEN_MAX)
+ die('Eusername_too_long');
+ if(strlen($login->password)==0)
+ die('Eno_password');
+ if(strlen($login->password)>PASSWORD_LEN_MAX)
+ die('Epassword_too_long');
+
+ $user = user::get_from_username($sqlc, $login->username);
+ if(!$user)
+ die('Euser_not_exist');
+
+ if(hash('sha512', $login->password) != $user->password)
+ die('Ewrong_password');
+
+ setcookie('uid', $user->uid, time() + 31536000, '/toj/');
+ setcookie('usec', hash('sha512', $user->uid.SEC_SALT), time() + 31536000, '/toj/');
+
+ echo('S');
+}
+
+db_close($sqlc);
+
+?>