diff --git a/code/web/api/client/auth.php b/code/web/api/client/auth.php new file mode 100644 index 000000000..cab8a5886 --- /dev/null +++ b/code/web/api/client/auth.php @@ -0,0 +1,49 @@ +. + */ + +require_once(RYAPI_PATH.'client/config.php'); + +// Og (non-ryzom.com) method +function ryzom_authenticate_with_serverkey($cid, $name, $authserver, $authkey) { + global $_RYZOM_API_CONFIG; + $fn = $_RYZOM_API_CONFIG['auth_script'].'?name='.$name.'&cid='.$cid.'&authkey='.$authkey.'&authserver='.$authserver; + + $res = file_get_contents($fn); + return $res == '1'; +} + +// Ig method +function ryzom_authenticate_ingame($cid, $name, $authkey) { + global $_RYZOM_API_CONFIG; + $fn = $_RYZOM_API_CONFIG['auth_script'].'?name='.$name.'&cid='.$cid.'&authkey='.$authkey.'&ig=1'; + + $res = file_get_contents($fn); + echo $res; + return $res == '1'; +} + +// Session method +function ryzom_authenticate_with_session($name, $redirect) { + global $_RYZOM_API_CONFIG; + $fn = $_RYZOM_API_CONFIG['auth_script'].'?name='.$name; + + $res = file_get_contents($fn); + return $res == '1'; +} + +?> diff --git a/code/web/api/client/config.php.default b/code/web/api/client/config.php.default new file mode 100644 index 000000000..3c8ca869d --- /dev/null +++ b/code/web/api/client/config.php.default @@ -0,0 +1,20 @@ +. + */ + +// Url where player_auth.php is located +define('RYAPI_AUTH_SCRIPT', ''); diff --git a/code/web/api/client/user.php b/code/web/api/client/user.php new file mode 100644 index 000000000..de526dcca --- /dev/null +++ b/code/web/api/client/user.php @@ -0,0 +1,23 @@ +. + */ + +function ryzom_user_get_info($cid) { + return Array(); +} + +?> diff --git a/code/web/api/client/utils.php b/code/web/api/client/utils.php new file mode 100644 index 000000000..62a2de0c8 --- /dev/null +++ b/code/web/api/client/utils.php @@ -0,0 +1,3 @@ + diff --git a/code/web/api/common/auth.php b/code/web/api/common/auth.php new file mode 100644 index 000000000..b6bcdd799 --- /dev/null +++ b/code/web/api/common/auth.php @@ -0,0 +1,57 @@ +The application '._t(APP_NAME).' require authentication. Please enter your credentials'; + + $c .= '
'.$welcome_message.'

'; + + if ($user['message']) + $c .= '
'._t($user['message']).'

'; + $c .= ryzom_render_login_form($name, false); + echo ryzom_app_render(_t('app_'.APP_NAME), $c); + exit; + } + return false; + } + } + + if ($lang) + $_SESSION['lang'] = $lang; + + // get user informations + $user = ryzom_user_get_info($cid); + $user['lang'] = $_SESSION['lang']; + + $user['id'] = ryzom_get_user_id($cid, $user['char_name'], $user['creation_date']); + unset($user['last_played_date']); + unset($user['creation_date']); + return true; +} + +?> diff --git a/code/web/api/common/config.php.default b/code/web/api/common/config.php.default new file mode 100644 index 000000000..3a00bb04e --- /dev/null +++ b/code/web/api/common/config.php.default @@ -0,0 +1,28 @@ +. + */ + +// Url where the api is +define('RYAPI_URL', 'http://'); +if (!defined('RYAPI_PATH')) + define('RYAPI_PATH', dirname(__FILE__).'/'); +// used by "home" link +if (!defined('RYAPP_URL')) + define('RYAPP_URL', 'http://'); + +?> diff --git a/code/web/api/common/db_lib.php b/code/web/api/common/db_lib.php new file mode 100644 index 000000000..c3c7e8677 --- /dev/null +++ b/code/web/api/common/db_lib.php @@ -0,0 +1,422 @@ +. + */ + +define('SQL_DEF_TEXT', 0); +define('SQL_DEF_BOOLEAN', 1); +define('SQL_DEF_INT', 2); +define('SQL_DEF_DATE', 3); + + +// Wrapper for SQL database interactions +class ServerDatabase +{ + var $hostname = ''; + var $username = ''; + var $password = ''; + var $database = ''; + + var $_connection = Null; + + function ServerDatabase($host='', $user='', $passwd='', $dbname='') + { + if (($host != '') && ($user != '') && ($dbname != '')) + { + $this->hostname = $host; + $this->username = $user; + $this->password = $passwd; + $this->database = $dbname; + } + + if (($this->hostname != '') && ($this->username != '') && ($this->database != '')) + { + $this->_connection = mysql_connect($this->hostname, $this->username, $this->password) + or die("ERR1"); // ace . $this->get_error()); + $this->select_db($this->database); + } + } + + function close() + { + @mysql_close($this->_connection); + } + + function query($sql_statement) + { + $result = mysql_query($sql_statement, $this->_connection); + return $result; + } + + function select_db($dbname) { + $this->database = $dbname; + mysql_select_db($this->database, $this->_connection) or die("Database selection error : " . $this->get_error()); + } + + function num_rows($result) + { + return @mysql_num_rows($result); + } + + function fetch_row($result, $result_type=MYSQL_BOTH) + { + return @mysql_fetch_array($result, $result_type); + } + + function fetch_assoc($result) + { + return @mysql_fetch_array($result, MYSQL_ASSOC); + } + + + function query_single_row($sql_statement) + { + $result = $this->query($sql_statement); + return @mysql_fetch_array($result); + } + + function free_result($result) + { + @mysql_free_result($result); + } + + function get_error() + { + return mysql_errno($this->_connection) .": ". mysql_error($this->_connection); + } + + function last_insert_id() + { + return @mysql_insert_id(); + } + + function change_to($host,$user,$pass,$dbname) + { + $this->close(); + $this->hostname = $host; + $this->username = $user; + $this->password = $pass; + $this->database = $dbname; + $this->ServerDatabase(); + } +} + + + + +class ryDB { + + private static $_instances = array(); + private $db; + private $defs = array(); + private $errors = ''; + + + private function __construct($db_name) { + global $_RYZOM_API_CONFIG; + + $this->db = new ServerDatabase(RYAPI_WEBDB_HOST, RYAPI_WEBDB_LOGIN, RYAPI_WEBDB_PASS, $db_name); + $this->db->query("SET NAMES utf8"); + } + + public static function getInstance($db_name) { + if (!array_key_exists($db_name, self::$_instances)) + self::$_instances[$db_name] = new ryDB($db_name); + + self::$_instances[$db_name]->db->select_db($db_name); + return self::$_instances[$db_name]; + } + + function setDbDefs($table, $defs) { + $this->defs[$table] = $defs; + } + + function getDefs($table) { + if (!array_key_exists($table, $this->defs)) + die("Please add tables defs using setDbDefs('$table', \$defs)"); + return $this->defs[$table]; + } + + function getErrors() { + return $this->db->get_error(); + } + + function now() { + return date('Y-m-d H:i:s', time()); + } + + function toDate($timestamp) { + return date('Y-m-d H:i:s', $timestamp); + } + + function fromDate($string_date) { + return strtotime($string_date); + } + + function addDbTableProp($table, $props) { + $this->props[$table] = $props; + } + + /// DIRECT QUERY + function sqlQuery($sql) { + $result = $this->db->query($sql); + $ret = array(); + while ($row = $this->db->fetch_row($result)) { + $ret[] = $row; + } + return $ret; + } + + + /// QUERY /// + function sqlSelect($table, $props, $values=array(), $extra='') { + if ($table) { + $sql = "SELECT\n\t"; + $params = array(); + $test = array(); + if (!$props) + die("Bad Select on [$table] : missing props"); + + foreach($props as $name => $type) + $params[] = '`'.addslashes($name).'`'; + + foreach($values as $name => $value) { + if ($name[0] == '=') + $test[] = '('.addslashes(substr($name, 1)).' LIKE '.var_export($value, true).')'; + else + $test[] = '('.addslashes($name).' = '.var_export($value, true).')'; + } + $sql .= implode(",\n\t", $params)."\nFROM\n\t".$table."\n"; + if ($test) + $sql .= "WHERE\n\t".implode("\nAND\n\t", $test); + } + + if ($extra) + $sql .= "\n".$extra; + return $sql.';'; + + } + + function querySingle($table, $values=array(), $extra='') { + $sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra); + $result = $this->db->query($sql); + return $this->db->fetch_row($result); + } + + function querySingleAssoc($table, $values=array(), $extra='') { + $sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra); + $result = $this->db->query($sql); + return $this->db->fetch_row($result, MYSQL_ASSOC); + } + + function query($table, $values=array(), $extra='') { + $sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra); + $result = $this->db->query($sql); + $ret = array(); + while ($row = $this->db->fetch_row($result)) { + $ret[] = $row; + } + return $ret; + } + + function queryAssoc($table, $values=array(), $extra='') { + $sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra); + $result = $this->db->query($sql); + $ret = array(); + while ($row = $this->db->fetch_row($result, MYSQL_ASSOC)) { + $ret[] = $row; + } + return $ret; + } + + /// INSERT /// + function sqlInsert($table, $props, $vals) { + $sql = 'INSERT INTO '.$table.' '; + $params = array(); + $values = array(); + foreach($props as $name => $type) { + if (!isset($vals[$name])) + continue; + $params[] = $name; + switch ($type) { + case SQL_DEF_BOOLEAN: + $values[] = $vals[$name]?1:0; + break; + case SQL_DEF_INT: + $values[] = $vals[$name]; + break; + case SQL_DEF_DATE: // date + if (is_string($vals[$name])) + $values[] = "'".addslashes($vals[$name])."'"; + else + $values[] = "'".$this->toDate($vals[$name])."'"; + break; + default: + $values[] = "'".addslashes($vals[$name])."'"; + break; + } + } + $sql .= "(\n\t".implode(",\n\t", $params)."\n) VALUES (\n\t".implode(",\n\t", $values)."\n);"; + return $sql; + } + + function insert($table, $values) { + $sql = $this->sqlInsert($table, $this->getDefs($table), $values); + $this->db->query($sql); + return $this->db->last_insert_id(); + } + + /// DELETE /// + function sqlDelete($table, $values=array(), $where='') { + $sql = "DELETE FROM\n\t".$table."\n"; + $test = array(); + foreach($values as $name => $value) + $test[] = '('.addslashes($name).' = '.var_export($value, true).')'; + + if ($test or $where) + $sql .= "WHERE\n\t"; + if ($test) + $sql .= implode("\nAND\n\t", $test); + if ($where) + $sql .= "\n".$where; + return $sql.';'; + } + + function delete($table, $values=array(), $where='') { + $sql = $this->sqlDelete($table, $values, $where); + $result = $this->db->query($sql); + return $result; + } + + /// UPDATE /// + function sqlUpdate($table, $props, $vals, $tests, $extra) { + $sql = 'UPDATE '.$table.' SET '; + $params = array(); + $test = array(); + $values = array(); + foreach($props as $name => $type) { + if (!array_key_exists($name, $vals)) + continue; + switch ($type) { + case SQL_DEF_BOOLEAN: + $values[] = '`'.$name.'` = '.($vals[$name]?'1':'0'); + break; + case SQL_DEF_DATE: + if (is_string($vals[$name])) + $values[] = '`'.$name.'` = \''.addslashes($vals[$name]).'\''; + else + $values[] = '`'.$name.'` = \''.$this->toDate($vals[$name]).'\''; + break; + default: + $values[] = '`'.$name.'` = \''.addslashes($vals[$name]).'\''; + break; + } + } + $sql .= "\n\t".implode(",\n\t", $values)."\n"; + + foreach($tests as $name => $value) { + $test[] = '('.addslashes($name).' = '.var_export($value, true).')'; + } + if ($test) + $sql .= "WHERE\n\t".implode("\nAND\n\t", $test); + + $sql .= "\n".$extra; + + return $sql; + } + + + function update($table, $values=array(), $test=array(), $extra='') { + $sql = $this->sqlUpdate($table, $this->getDefs($table), $values, $test, $extra); + $result = $this->db->query($sql); + return $result; + } + + function sqlInsertOrUpdate($table, $props, $vals) { + $sql = $this->sqlInsert($table, $props, $vals); + $sql = substr($sql, 0, strlen($sql)-1); + $params = array(); + $test = array(); + $values = array(); + foreach($props as $prop) { + if (!array_key_exists($prop[2], $vals)) + continue; + $type = $prop[0]; + $check = $prop[1]; + $name = $prop[2]; + if ($type{0} == '#') + $type = substr($type, 1); + if (($type{0} == '>') or ($type == 'id')) + continue; + switch ($type) { + case 'trad': + $values[] = '`'.$name."` = '".addslashes($vals[$name])."'"; + break; + case 'textarea': + case 'string': + case 'option': + $values[] = '`'.$name."` = '".addslashes($vals[$name])."'"; + break; + case 'id': + case 'int': + case 'float': + $values[] = '`'.$name.'` = '.addslashes($vals[$name]); + break; + case 'bool': + $values[] = '`'.$name.'` = '.($vals[$name]?'1':'0'); + break; + } + } + $sql .= "\nON DUPLICATE KEY UPDATE\n\t".implode(",\n\t", $values)."\n"; + return $sql; + } + + function insertOrUpdate($table, $values) { + $sql = $this->sqlInsertOrUpdate($table, $this->getDefs($table), $values); + return $result; + } + + + /// Display + function getTableHtml($name, $params, $values, $order_by='') + { + $ret = ''; + $tr_header = ''; + $ret .= _s('t header', $tr_header); + $i = 0; + if (!$values) + return ''; + $current_section = ''; + foreach ($values as $rows) { + if ($order_by && $rows[$order_by] != $current_section) { + $current_section = $rows[$order_by]; + if ($current_section != '0') + $ret .= _s('t row ', ''.str_repeat('', count($params)-1)); + } + $td = ''; + foreach ($params as $test => $param) + $td .= ''; + $ret .= _s('t row '.strval($i % 2), $td); + $i++; + } + $ret .= '
 '; + $tr_header .= implode(' ', array_keys($params)).''._s('section', $current_section).''._s('section', ' ').' '.$rows[$param].'
'; + return $ret; + } + +} + +?> diff --git a/code/web/api/common/logger.php b/code/web/api/common/logger.php new file mode 100644 index 000000000..f4909e721 --- /dev/null +++ b/code/web/api/common/logger.php @@ -0,0 +1,43 @@ +log_indent += $indent; + if ($log) { + $tabs = str_repeat(" ", $this->log_indent); + $a = $tabs.str_replace("\n", "\n ".$tabs, $log); + $this->logs[] = ''.$a.''; + } + } + + function addPrint($log, $color='#FFFF00') { + $this->logs[] = ''.$log.''; + } + + function addError($log) { + $this->logs[] = ' ERROR: '.$log.''; + } + + function getLogs() { + $ret = ''; + if ($this->logs && $this->enable) + $ret = "Debug\n".implode("\n", $this->logs); + $this->logs = array(); + return $ret; + } +} + + +?> diff --git a/code/web/api/common/render.php b/code/web/api/common/render.php new file mode 100644 index 000000000..a2ec31795 --- /dev/null +++ b/code/web/api/common/render.php @@ -0,0 +1,218 @@ +. + */ + +function ryzom_app_render($title, $content, $bgcolor='', $javascript=array(), $homeLink=false) { + $c = ''; + // Render header + $title_prefix = ''; + if (ON_IPHONE) { + $title_prefix = 'Ryzom - '; + } + + if (!$bgcolor) + $bgcolor = '#000000'.(RYZOM_IG?'00':''); + + $c .= ''."\n"; + $c .= ' + '."\n"; + $c .= ' '.$title_prefix.(translation_exists($title)?_t($title):$title).''."\n"; + $c .= ' '."\n"; + + if (!RYZOM_IG) { + $c .= ryzom_render_header(); + $c .= ryzom_render_header_www(); + } + + $events = ON_IPHONE ? 'onorientationchange="updateOrientation();" ' : ''; + + $c .= ' '."\n"; + + $c .= ' '."\n"; + + // Javascript + $js_code = ''; + foreach ($javascript as $js) + $js_code .= ''; + $c .= $js_code; + + if (RYZOM_IG) + $c .= $content; + else{ + $c .= ryzom_render_www(ryzom_render_window($title, $content, $homeLink)); + } + + $c .= ''; + return $c; +} + +function ryzom_render_header() { + if (ON_IPHONE) { + return ''; + } else { + return ' '; + } +} + +// Call this inside the part if you want to use ryzom_render_www +function ryzom_render_header_www() { + if (ON_IPHONE) { + return ' + + + + + '; + } else { + return ' + +'; + } +} + +// Render a Ryzom style window +function ryzom_render_window($title, $content, $homeLink=false) { + return ryzom_render_window_begin($title, $homeLink) . $content . ryzom_render_window_end(); +} + +function ryzom_render_window_begin($title, $homeLink=false) { + + if ($homeLink === false) + $homeLink = ''._t('home').''; + + return ' +
+
+
'.$title_prefix.(translation_exists($title)?_t($title):$title).$homeLink.'
+
+
+
+
+'; +} + +function ryzom_render_window_end() { + return '
+
'.ryLogger::getInstance()->getLogs().'
+

powered by ryzom-api

+
+ '; +} + +// Render a webpage using www.ryzom.com style +function ryzom_render_www($content) { + return ryzom_render_www_begin() . $content . ryzom_render_www_end(); +} + +function ryzom_render_www_begin($url='') { + $style1 = 'position: relative; padding-top: 20px; padding-right: 30px; margin-bottom: -3px'; + $style2 = 'position: absolute; bottom: 0; right: 0; '; + if (ON_IPHONE) { + $style1 = 'position: relative; padding-top: 30px; padding-right: 30px; '; + $style2 = 'position: fixed; top: 0; right: 0; padding-right: 0px;'; + $marginBottom = ''; + } + if (!$url) { + $url_params = parse_query($_SERVER['REQUEST_URI']); + unset($url_params['lang']); + + $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.http_build_query($url_params); + } + return ' +
+
+
+ English + French + German + Russian +
+ +
+
+'; +} + +function ryzom_render_www_end() { + return '
'; +} + +function ryzom_render_login_form($char, $aligned=true) { + $c = ''; + if ($aligned) { + $c .= '
'; + $c .= ''; + $c .= ''; + $c .= ''; + $c .= ''; + $c .= ''; + } else { + $c .= '
'._t('enter_char').'
'._t('enter_password').'
'; + $c .= ''; + $c .= ''; + $c .= ''; + $c .= ''; + $c .= ''; + } + $c .= '
'._t('login').'
'._t('password').'
'; + return $c; +} + +?> diff --git a/code/web/api/common/user.php b/code/web/api/common/user.php new file mode 100644 index 000000000..62a2de0c8 --- /dev/null +++ b/code/web/api/common/user.php @@ -0,0 +1,3 @@ + diff --git a/code/web/api/common/utils.php b/code/web/api/common/utils.php new file mode 100644 index 000000000..9f12fdfc1 --- /dev/null +++ b/code/web/api/common/utils.php @@ -0,0 +1,182 @@ + $v) { + if (is_int($k) && $prefix != null) { + $k = urlencode($prefix . $k); + } + if ((!empty($key)) || ($key === 0)) $k = $key.'['.urlencode($k).']'; + if (is_array($v) || is_object($v)) { + array_push($ret, http_build_query($v, '', $sep, $k)); + } else { + array_push($ret, $k.'='.urlencode($v)); + } + } + if (empty($sep)) $sep = ini_get('arg_separator.output'); + return implode($sep, $ret); + } +} + + +/*** + * + * Translation utilities + * + * ***/ + +function translation_exists($id) { + global $user, $ryzom_texts; + return isset($ryzom_texts[$id]) && isset($ryzom_texts[$id][$user['lang']]); +} + +// Translate the $id in the selected language +function get_translation($id, $lang, $args=array()) { + global $ryzom_texts, $user; + if(!isset($ryzom_texts[$id])) return '{'.$id.'}'; + if(!isset($ryzom_texts[$id][$lang])) return '{'.$id.'['.$lang.']}'; + if($ryzom_texts[$id][$lang] == '' && isset($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args); + return @vsprintf($ryzom_texts[$id][$lang], $args); +} + + +// Translate the $id in the user language +function _t($id, $args=array()) { + global $ryzom_texts, $user; + + $a = ''; + if ($args) { + if (is_array($args)) { + $a = array(); + foreach ($args as $arg) + $a[] = strval($arg); + $a = ' '.implode(', ', $a); + } else + $a = ' '.strval($args); + } + if(!isset($ryzom_texts[$id])) return '{'.$id.$a.'}'; + if(!isset($ryzom_texts[$id][$user['lang']])) return '{'.$id.'['.$user['lang'].']'.$a.'}'; + if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['en']) && $ryzom_texts[$id]['en'] != '') return @vsprintf($ryzom_texts[$id]['en'], $args); + if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['fr']) && $ryzom_texts[$id]['fr'] != '') return '{'.$id.$a.'}'; + if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['de']) && $ryzom_texts[$id]['de'] != '') return '{'.$id.$a.'}'; + return @vsprintf($ryzom_texts[$id][$user['lang']], $args); +} + +/*** + * + * Ryzom time + * + * ***/ + + + +// Get a human and translated readable time, for example "3 days ago" +function ryzom_relative_time($timestamp) { + global $ryzom_periods, $user; + $difference = time() - $timestamp; + $lengths = array("60","60","24","7","4.35","12","10"); + + if ($difference >= 0) { // this was in the past + $ending = _t('ago'); + } else { // this was in the future + $difference = -$difference; + $ending = _t('to_go'); + } + for($j = 0,$m=count($lengths); $j<$m && $difference >= $lengths[$j]; $j++) + $difference /= $lengths[$j]; + // round hours as '1.2 hours to go' + $difference = round($difference, ($j == 2) ? 1 : 0); + + $form = ($difference == 1) ? 'singular' : 'plural'; + + // Handle exceptions + // French uses singular form if difference = 0 + if ($user['lang'] == 'fr' && ($difference == 0)) { + $form = 'singular'; + } + // Russian has a different plural form for plurals of 2 through 4 + if ($user['lang'] == 'ru' && ($form == 'plural')) { + if ($difference < 5) { + $form = '2-4'; + } + } + + $final = $ryzom_periods[$user['lang']][$form][$j]; + $text = _t('date_format', array($difference, $final, $ending)); + return $text; +} + +// Get a human and translated absolute date +function ryzom_absolute_time($timestamp) { + global $user, $ryzom_daysofweek, $ryzom_monthnames; + $day_of_month = date("j", $timestamp); + $dow = date("w", $timestamp); + $month = date("n", $timestamp); + $day_of_week = $ryzom_daysofweek[$user['lang']][$dow]; + $month_str = $ryzom_monthnames[$user['lang']][$month-1]; + $text = _t("absolute_date_format", array($day_of_month, $day_of_week, $month_str, $month, date("m", $timestamp), date("d", $timestamp))); + return $text; +} + +/*** + * + * Debug tools + * + * ***/ + +function p($var, $value=NULL) { + ob_start(); + debug_print_backtrace(); + $bt = ob_get_contents(); + ob_end_clean(); + $bt = explode("\n",$bt); + $bt = explode('[', $bt[1]); + ob_start(); + echo ''.substr($bt[count($bt)-1], 0, -1)."\n"; + if ($value !== NULL) { + echo ''.$var.' : '; + $var = $value; + } + //if (is_array($var)) + echo '
';
+	print_r($var);
+	echo '
'; +// else + // var_dump($var); + ryLogger::getInstance()->addPrint(ob_get_contents()); + ob_end_clean(); +} + +?> diff --git a/code/web/api/data/css/ryzom_iphone.css b/code/web/api/data/css/ryzom_iphone.css new file mode 100644 index 000000000..c837ffbf4 --- /dev/null +++ b/code/web/api/data/css/ryzom_iphone.css @@ -0,0 +1,248 @@ +/* Copyright (C) 2009 Winch Gate Property Limited + * + * This file is part of ryzom_api. + * ryzom_api is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ryzom_api is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ryzom_api. If not, see . + */ + +html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 { + margin:0; + padding:0; + -webkit-text-size-adjust: none; +} + +body { + font-size: 14px; + background: black; + font-family: Helvetica; +} + +ul li { + padding: 0px 4px 10px 2px; + list-style: circle outside; +} +ol li { + padding: 0px 4px 10px 2px; +} +.ryzom-ui p { + padding-bottom:8px; +} + +#main { + clear: both; + padding-top: 0px; + overflow:auto; + margin-left:auto; + margin-right:auto; + text-align:left +} +.error { + padding:.5em; + background:#ff5555; + color:white; + font-weight:bold +} +/*----------------------------- + ORIENTATION +-----------------------------*/ + +.content_wide, +.content_normal { + display:none; +} + +.show_normal { + width: 320px; +} + +.show_wide { + width: 480px; +} + +.show_wide .content_wide, +.show_normal .content_normal { + display: block; +} + +/* ---------------------- */ + + +.ryzom-ui { + color: white; +} +.ryzom-ui input, .ryzom-ui select { + border-top: 1px solid #030403; + border-right: 1px solid #6e7f57; + border-bottom: 1px solid #889e6c; + border-left: 1px solid #272d1f; + background-color: #37402b; + color: #ddd; + font-size: 16px; + margin: 2px 0 5px 0; +} +.ryzom-ui input[type=text] { + width: 96%; +} + +.ryzom-ui textarea { + width: 96%; + background-color: black; + color: white; + font-size: 16px; + font-family: Helvetica; +} +/* input[type=submit] will make IE6 to ignore whole CSS rule, so cant combine this with .ryzom-ui-button below */ +input[type=submit] { + border-bottom: 1px solid #030403; + border-left: 1px solid #6e7f57; + border-top: 1px solid #889e6c; + border-right: 1px solid #272d1f; + background-color: #435120; +} +input.ryzom-ui-button, .ryzom-ui-button { + border-bottom: 1px solid #030403; + border-left: 1px solid #6e7f57; + border-top: 1px solid #889e6c; + border-right: 1px solid #272d1f; + background-color: #435120; +} + +a, a:visited {color:orange} + +a:hover {color:orange} + +a.ryzom-ui-button, a.ryzom-ui-button:visited { + color: white; + padding: 0 .5em; + text-decoration: none; +} +a.ryzom-ui-button:hover { + background: #536130; + color: #ddd; +} +/* window without title - just borders */ +.ryzom-ui-tl { +} +.ryzom-ui-tr { +} +.ryzom-ui-t { + background-image: url(skin_t.gif); + background-repeat: repeat-x; + background-position: left top; + height: 8px; + margin: 0; +} +/* window with proper header */ +.ryzom-ui-header .ryzom-ui-tl { + margin: 0px 0px; + height: 32px; +} +.ryzom-ui-header .ryzom-ui-tr { + height: 32px; +} +.ryzom-ui-header .ryzom-ui-t { + background-image: url(skin_header_m.gif); + background-repeat: repeat-x; + background-position: left top; + padding: 7px 0 0 12px; + height: 32px; + text-transform: uppercase; + color: white; + border-top: 1px solid #030403; +} +/* window body */ +.ryzom-ui-l { +} +.ryzom-ui-r { +} +.ryzom-ui-m { + margin: 0 0px; + padding: 0px; + background-image: url(skin_blank.png); + background-repeat: repeat; +} +.ryzom-ui-body { + background-image: url(skin_blank_inner.png); + background-repeat: repeat; + /* leave 5px room after bottom border */ + margin: 0 8px 5px 2px; + padding: 5px 5px 5px 5px; + border-top: 1px solid #030403; + border-right: 1px solid #6e7f57; + border-bottom: 1px solid #889e6c; + border-left: 1px solid #272d1f; +} +/* window bottom border */ +.ryzom-ui-bl { + height: 8px; +} +.ryzom-ui-br { + height: 8px; +} +.ryzom-ui-b { + height: 8px; + margin: 0 8px; +} +.ryzom-ui-notice { + margin: 0px; + padding: 0px; + color: #999; + text-align: center; +} +a.ryzom-ui-notice, a.ryzom-ui-notice:visited { + margin: 0px; + padding: 0px; + color: #BBB; + padding: 0 .5em; + text-decoration: underline; +} +a.ryzom-ui-notice:hover { + color: gray; +} + +.ryzom-ui-t .ryzom-ui-text-button { + font-size: 85%; +} +a.ryzom-ui-text-button, a:visited.ryzom-ui-text-button { + color:#FFFF11; + text-decoration:none; +} + +.ryzom-ui-text-button { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} +.ryzom-ui-text-button { + padding: 0;margin: 0; + border-color: #ff8 #ff3 #ff3 #ff8; + border-width: 1px; + border-style: solid; + padding: 0px 4px; + color: white; +} + +.ryzom-ui-wrap-ul { + float: left; + text-align: center; + padding: 0; + list-style: none; +} + +.ryzom-ui-wrap-li { + float: left; + margin: 0 0 10px 5px; + width: 6.1em; + list-style: none; + height: 70px; +} diff --git a/code/web/api/data/css/ryzom_ui.css b/code/web/api/data/css/ryzom_ui.css new file mode 100644 index 000000000..8342b77f8 --- /dev/null +++ b/code/web/api/data/css/ryzom_ui.css @@ -0,0 +1,227 @@ +/* Copyright (C) 2009 Winch Gate Property Limited + * + * This file is part of ryzom_api. + * ryzom_api is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ryzom_api is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ryzom_api. If not, see . + */ + +/* + * Check ryzom_api/functions_render.php for easy php function to render ryzom layout or use this following html: + * +
+
+
+
+
+
+
+
+
+ */ + +.ryzom-ui { + color: white; +} +.ryzom-ui input, .ryzom-ui select { + border-top: 1px solid #030403; + border-right: 1px solid #6e7f57; + border-bottom: 1px solid #889e6c; + border-left: 1px solid #272d1f; + background-color: #37402b; + color: #ddd; + font-size: 12px; + margin: 2px 0 5px 0; +} +.ryzom-ui input[type=text] { + width: 100%; +} + +.ryzom-ui textarea { + width: 98%; +} + +/* input[type=submit] will make IE6 to ignore whole CSS rule, so cant combine this with .ryzom-ui-button below */ +input[type=submit] { + border-bottom: 1px solid #030403; + border-left: 1px solid #6e7f57; + border-top: 1px solid #889e6c; + border-right: 1px solid #272d1f; + background-color: #435120; +} +input.ryzom-ui-button, .ryzom-ui-button { + border-bottom: 1px solid #030403; + border-left: 1px solid #6e7f57; + border-top: 1px solid #889e6c; + border-right: 1px solid #272d1f; + background-color: #435120; +} +a.ryzom-ui-button, a.ryzom-ui-button:visited { + color: white; + padding: 0 .5em; + text-decoration: none; +} +a.ryzom-ui-button:hover { + background: #536130; + color: #ddd; +} +/* window without title - just borders */ +.ryzom-ui-tl { + background-image: url(skin_tl.gif); + background-repeat: no-repeat; + background-position: left top; + width: 100%; height: 8px; +} +.ryzom-ui-tr { + background-image: url(skin_tr.gif); + background-repeat: no-repeat; + background-position: right top; + height: 8px; +} +.ryzom-ui-t { + background-image: url(skin_t.gif); + background-repeat: repeat-x; + background-position: left top; + height: 8px; + margin: 0 8px; +} +/* window with proper header */ +.ryzom-ui-header .ryzom-ui-tl { + margin: 0px 0px; + background-image: url(skin_header_l.gif); + background-repeat: no-repeat; + background-position: left top; + height: 32px; +} +.ryzom-ui-header .ryzom-ui-tr { + background-image: url(skin_header_r.gif); + background-repeat: no-repeat; + background-position: right top; + height: 32px; +} +.ryzom-ui-header .ryzom-ui-t { + background-image: url(skin_header_m.gif); + background-repeat: repeat-x; + background-position: left top; + margin-left: 12px; + margin-right: 26px; + padding-top: 9px; + height: 32px; + text-transform: uppercase; + color: white; +} +/* window body */ +.ryzom-ui-l { + background-image: url(skin_l.gif); + background-position: left top; + background-repeat: repeat-y; + width: 100%; +} +.ryzom-ui-r { + background-image: url(skin_r.gif); + background-position: right top; + background-repeat: repeat-y; + width: 100%; +} +.ryzom-ui-m { + margin: 0 8px; + padding: 8px; + background-image: url(skin_blank.png); + background-repeat: repeat; +} +.ryzom-ui-body { + background-image: url(skin_blank_inner.png); + background-repeat: repeat; + /* leave 5px room after bottom border */ + margin: 0px 0 5px 0; + padding: 10px 10px 5px 10px; + border-top: 1px solid #030403; + border-right: 1px solid #6e7f57; + border-bottom: 1px solid #889e6c; + border-left: 1px solid #272d1f; +} +/* window bottom border */ +.ryzom-ui-bl { + background-image: url(skin_bl.gif); + background-repeat: no-repeat; + background-position: left top; + height: 8px; +} +.ryzom-ui-br { + background-image: url(skin_br.gif); + background-repeat: no-repeat; + background-position: right top; + height: 8px; +} +.ryzom-ui-b { + background-image: url(skin_b.gif); + background-repeat: repeat-x; + background-position: left top; + height: 8px; + margin: 0 8px; +} +.ryzom-ui-notice { + margin: 0px; + padding: 0px; + color: #333; + text-align: center; +} +a.ryzom-ui-notice, a.ryzom-ui-notice:visited { + margin: 0px; + padding: 0px; + color: #555; + padding: 0 .5em; + text-decoration: underline; +} +a.ryzom-ui-notice:hover { + color: gray; +} + +.ryzom-ui-t .ryzom-ui-text-button { + font-size: 85%; +} +a.ryzom-ui-text-button, a:visited.ryzom-ui-text-button { + color:#FFFF11; + text-decoration:none; +} + +.ryzom-ui-text-button { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} +.ryzom-ui-text-button { + padding: 0;margin: 0; + border-color: #ff8 #ff3 #ff3 #ff8; + border-width: 1px; + border-style: solid; + padding: 0px 4px; + color: white; +} + +.ryzom-ui-wrap-ul { + float: left; + text-align: center; + padding: 0; + list-style: none; + margin-top: -5px; + margin-bottom: -20px; +} + +.ryzom-ui-wrap-li { + float: left; + margin: 0 5px 10px 5px; + width: 6.1em; + padding: 0; + list-style: none; + height: 70px; +} diff --git a/code/web/api/data/css/skin_b.gif b/code/web/api/data/css/skin_b.gif new file mode 100644 index 000000000..a1a0390bc Binary files /dev/null and b/code/web/api/data/css/skin_b.gif differ diff --git a/code/web/api/data/css/skin_bl.gif b/code/web/api/data/css/skin_bl.gif new file mode 100644 index 000000000..459dc0065 Binary files /dev/null and b/code/web/api/data/css/skin_bl.gif differ diff --git a/code/web/api/data/css/skin_blank.png b/code/web/api/data/css/skin_blank.png new file mode 100644 index 000000000..0fefeaab0 Binary files /dev/null and b/code/web/api/data/css/skin_blank.png differ diff --git a/code/web/api/data/css/skin_blank_inner.png b/code/web/api/data/css/skin_blank_inner.png new file mode 100644 index 000000000..b728324ef Binary files /dev/null and b/code/web/api/data/css/skin_blank_inner.png differ diff --git a/code/web/api/data/css/skin_br.gif b/code/web/api/data/css/skin_br.gif new file mode 100644 index 000000000..3a01335f8 Binary files /dev/null and b/code/web/api/data/css/skin_br.gif differ diff --git a/code/web/api/data/css/skin_header_l.gif b/code/web/api/data/css/skin_header_l.gif new file mode 100644 index 000000000..288016a1d Binary files /dev/null and b/code/web/api/data/css/skin_header_l.gif differ diff --git a/code/web/api/data/css/skin_header_m.gif b/code/web/api/data/css/skin_header_m.gif new file mode 100644 index 000000000..48d539173 Binary files /dev/null and b/code/web/api/data/css/skin_header_m.gif differ diff --git a/code/web/api/data/css/skin_header_r.gif b/code/web/api/data/css/skin_header_r.gif new file mode 100644 index 000000000..c8711c2f5 Binary files /dev/null and b/code/web/api/data/css/skin_header_r.gif differ diff --git a/code/web/api/data/css/skin_l.gif b/code/web/api/data/css/skin_l.gif new file mode 100644 index 000000000..4ca369db5 Binary files /dev/null and b/code/web/api/data/css/skin_l.gif differ diff --git a/code/web/api/data/css/skin_r.gif b/code/web/api/data/css/skin_r.gif new file mode 100644 index 000000000..3c821e89e Binary files /dev/null and b/code/web/api/data/css/skin_r.gif differ diff --git a/code/web/api/data/css/skin_t.gif b/code/web/api/data/css/skin_t.gif new file mode 100644 index 000000000..aefc8416b Binary files /dev/null and b/code/web/api/data/css/skin_t.gif differ diff --git a/code/web/api/data/css/skin_tl.gif b/code/web/api/data/css/skin_tl.gif new file mode 100644 index 000000000..7dd640272 Binary files /dev/null and b/code/web/api/data/css/skin_tl.gif differ diff --git a/code/web/api/data/css/skin_tr.gif b/code/web/api/data/css/skin_tr.gif new file mode 100644 index 000000000..7543d7221 Binary files /dev/null and b/code/web/api/data/css/skin_tr.gif differ diff --git a/code/web/api/data/img/bg.jpg b/code/web/api/data/img/bg.jpg new file mode 100644 index 000000000..7d07d98c7 Binary files /dev/null and b/code/web/api/data/img/bg.jpg differ diff --git a/code/web/api/data/img/lang/de.png b/code/web/api/data/img/lang/de.png new file mode 100644 index 000000000..767abe088 Binary files /dev/null and b/code/web/api/data/img/lang/de.png differ diff --git a/code/web/api/data/img/lang/en.png b/code/web/api/data/img/lang/en.png new file mode 100644 index 000000000..2673310cc Binary files /dev/null and b/code/web/api/data/img/lang/en.png differ diff --git a/code/web/api/data/img/lang/fr.png b/code/web/api/data/img/lang/fr.png new file mode 100644 index 000000000..420474693 Binary files /dev/null and b/code/web/api/data/img/lang/fr.png differ diff --git a/code/web/api/data/img/lang/ru.png b/code/web/api/data/img/lang/ru.png new file mode 100644 index 000000000..53aaf57be Binary files /dev/null and b/code/web/api/data/img/lang/ru.png differ diff --git a/code/web/api/data/img/lang/sp.png b/code/web/api/data/img/lang/sp.png new file mode 100644 index 000000000..5ef5123ba Binary files /dev/null and b/code/web/api/data/img/lang/sp.png differ diff --git a/code/web/api/data/img/logo.gif b/code/web/api/data/img/logo.gif new file mode 100644 index 000000000..adc59fd29 Binary files /dev/null and b/code/web/api/data/img/logo.gif differ diff --git a/code/web/api/index.php b/code/web/api/index.php new file mode 100644 index 000000000..70e3eb1d2 --- /dev/null +++ b/code/web/api/index.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/code/web/api/player_auth.php b/code/web/api/player_auth.php new file mode 100644 index 000000000..984a96fe7 --- /dev/null +++ b/code/web/api/player_auth.php @@ -0,0 +1,44 @@ +. + */ + +require_once('ryzom_api.php'); +$cid = ryzom_get_param('cid'); +$name = ryzom_get_param('name'); +$authserver = ryzom_get_param('authserver'); +$authkey = ryzom_get_param('authkey'); + +if ($authserver) { + if (ryzom_authenticate_with_serverkey($cid, $name, $authserver, $authkey)) + die('1'); + die('0'); +} + +if (RYZOM_IG || ryzom_get_param('ig')) { + echo 'ig'; + if (ryzom_authenticate_ingame($cid, $name, $authkey)) { + echo 'ok'; + $user_infos = ryzom_user_get_info($cid); + echo ryzom_get_user_id($cid, $name, $user_infos['creation_date']); + die('1'); + } + die('0'); +} else { + echo ryzom_authenticate_with_session($name, $cid, $_RYZOM_API_CONFIG['base_url'].'index.php'); +} + +?> diff --git a/code/web/api/ryzom_api.php b/code/web/api/ryzom_api.php new file mode 100644 index 000000000..960405b03 --- /dev/null +++ b/code/web/api/ryzom_api.php @@ -0,0 +1,49 @@ +. + */ + +session_start(); + +// Global defines +if (!defined('ON_IPHONE')) { + if(isset($_SERVER['HTTP_USER_AGENT'])) + define('ON_IPHONE', strpos($_SERVER['HTTP_USER_AGENT'], 'Ryzom')); + else + define('ON_IPHONE', false); +} +if (!defined('RYZOM_IG')) { + if (isset($_SERVER['HTTP_USER_AGENT'])) + define('RYZOM_IG', strpos($_SERVER['HTTP_USER_AGENT'], 'Ryzom')); + else + define('RYZOM_IG', false); +} + +$includes = array('auth', 'config', 'utils', 'user'); + +foreach ($includes as $include) { + if ($_SERVER['HTTP_HOST'] == 'shard.nuneo.org' || $_SERVER['HTTP_HOST'] == 'app.ryzom.com') + require_once("server/$include.php"); + else + require_once("client/$include.php"); + + require_once("common/$include.php"); +} + +require_once("common/db_lib.php"); +require_once("common/render.php"); + +?> diff --git a/code/web/api/server/auth.php b/code/web/api/server/auth.php new file mode 100644 index 000000000..a8706fe8d --- /dev/null +++ b/code/web/api/server/auth.php @@ -0,0 +1,111 @@ +. + */ + +function ryzom_authenticate_with_serverkey($cid, $name, $authserver, $authkey) { + $rawkey = RYAPI_COOKIE_KEY.$name.$cid.$authserver; + $authkey = md5($rawkey); + if ($authkey != $authkey) return false; + return true; +} + +function ryzom_authenticate_ingame($cid, $name, $authkey) { + return file_get_contents(RYAPI_AUTH_SCRIPT) == '1'; +} + +// take the character name and the account password and check if it's valid +function ryzom_authenticate_with_char_and_password($character, $password, &$cid) { + $db = new ServerDatabase(RYAPI_NELDB_HOST, RYAPI_NELDB_LOGIN, RYAPI_NELDB_PASS, RYAPI_NELDB_RING); + $char = mysql_real_escape_string($character, $db->_connection); + $sql = "SELECT char_id, char_name, user_id, home_mainland_session_id FROM characters WHERE char_name = '$char'"; + $row = $db->query_single_row($sql); + $character = $row['char_name']; + $cid = $row['char_id']; + $uid = $row['user_id']; + mysql_select_db('nel', $db->_connection); + $sql = "SELECT Password FROM user WHERE UId = $uid"; + $row = $db->query_single_row($sql); + $ok = $row['Password'] == crypt($password, $row['Password']); + return $ok; +} + +function ryzom_authenticate_with_session(&$name, &$cid, &$error_message) { + $c = ''; + + $action = ryzom_get_param('action'); + if ($action == 'logout') { + unset($_SESSION['name']); + unset($_SESSION['cid']); + } + + if (isset($_SESSION['name']) && ($name == '' || $_SESSION['name'] == $name)) { + $name = $_SESSION['cid']; + $cid = $_SESSION['cid']; + return true; + } + + $char = ryzom_get_param('char'); + $password = ryzom_get_param('password'); + + if ($char && $password) { + // check credentials + if (ryzom_authenticate_with_char_and_password($char, $password, $cid)) { + $_SESSION['name'] = $char; + $_SESSION['cid'] = $cid; + return true; + } else { + $error_message = 'bad_auth'; + } + } + + return false; +} + + + +function ryzom_get_user_id($cid, $name, $creation_date) { + $name = strtolower($name); + + $db = ryDB::getInstance('webig'); + $db->setDbDefs('players', array('id' => SQL_DEF_INT, 'cid' => SQL_DEF_INT, 'name' => SQL_DEF_TEXT, 'creation_date' => SQL_DEF_DATE, 'deleted' => SQL_DEF_BOOLEAN)); + + $charProps = $db->querySingle('players', array('cid' => intval($cid), 'deleted' => 0)); + // new char => create record + if (!$charProps) { + $charProps = array('name' => $name, 'cid' => $cid, 'creation_date' => $creation_date, 'deleted' => 0); + $charProps['id'] = $db->insert('players', $charProps); + if (!$charProps['id']) + die('ryDb New Char Error'); + } else { + // char renamed => update record + if ($charProps['name'] != $name) + if (!$db->update('players', array('name' => $name), array('id' => $charProps['id']))) + die('ryDb Rename Char Error'); + + // char deleted and recreated => change to deleted + if ($charProps['creation_date'] != $creation_date) { + if (!$db->update('players', array('deleted' => 1), array('id' => $charProps['id']))) + die('ryDb Delete char Error: '.$db->getErrors()); + $charProps = array('name' => $name, 'cid' => $cid, 'creation_date' => $creation_date, 'deleted' => 0); + if (!$charProps['id'] = $db->insert('players', $charProps)) + die('ryDb New Char in Slot Error'); + } + } + return $charProps['id']; +} + +?> diff --git a/code/web/api/server/config.php.default b/code/web/api/server/config.php.default new file mode 100644 index 000000000..c55cf74f0 --- /dev/null +++ b/code/web/api/server/config.php.default @@ -0,0 +1,31 @@ +. + */ +define('RYAPI_WEBDB_HOST', 'localhost'); +define('RYAPI_WEBDB_LOGIN', 'localhost'); +define('RYAPI_WEBDB_PASS', 'localhost'); + +define('RYAPI_NELDB_HOST', 'localhost'); +define('RYAPI_NELDB_LOGIN', 'shard'); +define('RYAPI_NELDB_PASS', 'localhost'); +define('RYAPI_NELDB_RING', 'ring_open'); +define('RYAPI_NELDB_NEL', 'nel'); + +define('RYAPI_AUTH_SCRIPT', ''); +define('RYAPI_COOKIE_KEY', ''); + +?> diff --git a/code/web/api/server/user.php b/code/web/api/server/user.php new file mode 100644 index 000000000..9124191ae --- /dev/null +++ b/code/web/api/server/user.php @@ -0,0 +1,111 @@ +. + */ + +function ryzom_user_get_info($cid) { + // User information + global $_RYZOM_API_CONFIG; + $db = new ServerDatabase(RYAPI_NELDB_HOST, RYAPI_NELDB_LOGIN, RYAPI_NELDB_PASS, RYAPI_NELDB_RING); + $sql = "SELECT char_name, race, civilisation, cult, guild_id, creation_date, last_played_date FROM characters WHERE char_id = $cid"; + $result = $db->query($sql) or die('Could not query on ryzom_user_get_info'); + $found = $db->num_rows($result) >= 1; + if (!$found) + die('Could not found on ryzom_user_get_info'); + $row = $db->fetch_assoc($result); + $db->free_result($result); + if ($row) { + $row['race'] = substr($row['race'], 2); + $row['cult'] = substr($row['cult'], 2); + $row['civ'] = substr($row['civilisation'], 2); + if ($row['guild_id'] != '0') { + //$xml = @simplexml_load_file(ryzom_guild($row['guild_id'], false)); + $xml = false; + if ($xml !== false) { + $row['guild_icon'] = (string)$xml->icon; + $row['guild_name'] = (string)$xml->name; + $result = $xml->xpath("/guild/members/member[cid=$cid]"); + while(list( , $item) = each($result)) + $row['grade'] = (string)$item->grade; + } else { + $row['guild_name'] = 'UNKNOWN_GUILD_'.$row['guild_id']; // Unknow name (normal in yubo shard) + } + } + } + + $uid = intval($cid / 16); + $db = new ServerDatabase(RYAPI_NELDB_HOST, RYAPI_NELDB_LOGIN, RYAPI_NELDB_PASS, RYAPI_NELDB_NEL); + $sql = "SELECT Privilege FROM user WHERE UId = $uid"; + $result = $db->query($sql) or die("Could not query."); + $priv_row = $db->fetch_row($result, MYSQL_NUM); + $priv = $priv_row[0]; + $db->free_result($result); + $groups = array(); + + if (strpos($priv, ':DEV:') !== false) { + $groups[] = 'DEV'; + $groups[] = 'SGM'; + $groups[] = 'GM'; + $groups[] = 'EM'; + $groups[] = 'EG'; + $groups[] = 'VG'; + $groups[] = 'G'; + } + + if (strpos($priv, ':SGM:') !== false) { + $groups[] = 'SGM'; + $groups[] = 'GM'; + $groups[] = 'VG'; + $groups[] = 'G'; + } + + if (strpos($priv, ':GM:') !== false) { + $groups[] = 'GM'; + $groups[] = 'VG'; + $groups[] = 'G'; + } + + if (strpos($priv, ':VG:') !== false) { + $groups[] = 'VG'; + $groups[] = 'G'; + } + + if (strpos($priv, ':G:') !== false) { + $groups[] = 'G'; + } + + if (strpos($priv, ':SEM:') !== false) { + $groups[] = 'SEM'; + $groups[] = 'EM'; + $groups[] = 'EG'; + } + + if (strpos($priv, ':EM:') !== false) { + $groups[] = 'EM'; + $groups[] = 'EG'; + } + + if (strpos($priv, ':EG:') !== false) { + $groups[] = 'EG'; + } + + $groups[] = 'PLAYER'; + $row['groups'] = $groups; + + return $row; +} + +?> diff --git a/code/web/api/server/utils.php b/code/web/api/server/utils.php new file mode 100644 index 000000000..49860d24e --- /dev/null +++ b/code/web/api/server/utils.php @@ -0,0 +1,49 @@ +. + */ + + +function ryzom_name_to_file($name) +{ + $r = ''; + for ($i=0; $i= chr(127)) + $r .= sprintf("%%%02x", ord($name[$i])); + else + $r .= $name[$i]; + } + return $r; +} + +// ------------------------------------- +// get user home directory +// ------------------------------------- +function ryzom_get_user_dir($user) +{ + global $_RYZOM_API_CONFIG; + + if ($user == "") + die("INTERNAL ERROR CODE 1"); + + $user = ryzom_name_to_file($user); + return $_RYZOM_API_CONFIG['cookie_path'].'/'.$_RYZOM_API_CONFIG['shardid'].'/'.substr(strtolower($user), 0, 2).'/'.strtolower($user).'/'; +} + +?> diff --git a/code/web/app/app_test/favicon.png b/code/web/app/app_test/favicon.png new file mode 100644 index 000000000..623a56663 Binary files /dev/null and b/code/web/app/app_test/favicon.png differ diff --git a/code/web/app/app_test/index.php b/code/web/app/app_test/index.php new file mode 100644 index 000000000..95573dfe2 --- /dev/null +++ b/code/web/app/app_test/index.php @@ -0,0 +1,34 @@ +enable = true; + +// Debug log +p($user); + +// Update user acces on Db +$db = ryDB::getInstance(APP_NAME); +$db->setDbDefs('test', array('id' => SQL_DEF_INT, 'num_access' => SQL_DEF_INT)); + +$num_access = $db->querySingleAssoc('test', array('id' => $user['id'])); +if ($num_access) + $db->update('test', array('num_access' => ++$num_access['num_access']), array('id' => $user['id'])); +else + $db->insert('test', array('num_access' => $num_access['num_access']=1, 'id' => $user['id'])); + +// Content +$c = _t('access', $num_access['num_access']).'
'; + +echo ryzom_app_render(APP_NAME, $c); + +?> diff --git a/code/web/app/app_test/lang.php b/code/web/app/app_test/lang.php new file mode 100644 index 000000000..0a877c548 --- /dev/null +++ b/code/web/app/app_test/lang.php @@ -0,0 +1,15 @@ + + array ( + 'en' => 'User access this page %s times', + 'fr' => 'L\'utilisateur a accede a cette page %s fois', + 'de' => '', + 'ru' => '', + ), +); +if(isset($ryzom_texts)) + $ryzom_texts = array_merge ($__texts, $ryzom_texts); +else + $ryzom_texts = $__texts; +?> \ No newline at end of file diff --git a/code/web/app/config.php.default b/code/web/app/config.php.default new file mode 100644 index 000000000..0ecb2c302 --- /dev/null +++ b/code/web/app/config.php.default @@ -0,0 +1,26 @@ +. + */ + +define('RYAPP_URL', 'http://'); +define('RYAPP_PATH', dirname(__FILE__).'/'); +define('RYAPI_PATH', dirname(__FILE__).'/../api/'); + +include_once(RYAPI_PATH.'ryzom_api.php'); + +?> diff --git a/code/web/app/index.php b/code/web/app/index.php new file mode 100644 index 000000000..ed90c42b2 --- /dev/null +++ b/code/web/app/index.php @@ -0,0 +1,35 @@ +'._t('welcome', $user['char_name']).''; +} else { + if (!RYZOM_IG) { + if ($user['message']) + $c .= '
'._t($user['message']).'

'; + $c .= ryzom_render_login_form(ryzom_get_param('name')); + } +} + +foreach ($apps as $app) { + $c .= ''._t($app).'
'; +} + +if($logged) $c .= '
'._t('logout').''; + +echo ryzom_app_render('Ryzom', $c); + +?> \ No newline at end of file diff --git a/code/web/app/lang.php b/code/web/app/lang.php new file mode 100644 index 000000000..4780fcd00 --- /dev/null +++ b/code/web/app/lang.php @@ -0,0 +1,371 @@ + + array ( + 'en' => 'Welcome %s', + 'fr' => 'Bienvenue %s', + 'de' => 'Willkommen %s', + 'ru' => 'Добро пожаловать %s', + ), + 'latest_news_rp' => + array ( + 'en' => 'Latest RP news', + 'fr' => 'Dernières nouvelles RP', + 'de' => 'Letzte RP-Nachrichten', + 'ru' => 'Ролевые новости', + ), + 'latest_news_off' => + array ( + 'en' => 'Latest Ryzom news', + 'fr' => 'Dernières nouvelles de Ryzom', + 'de' => 'Letzte Ryzom-Nachrichten', + 'ru' => 'Последние новости Ризома', + ), + 'avail_apps' => + array ( + 'en' => 'Available applications', + 'fr' => 'Applications disponibles', + 'de' => 'Verfügbare Anwendungen', + 'ru' => 'Доступные приложения', + ), + 'home' => + array ( + 'en' => 'Home', + 'fr' => 'Accueil', + 'de' => 'Home', + 'ru' => 'К началу', + ), + 'logout' => + array ( + 'en' => 'Log out', + 'fr' => 'se déconnecter', + 'de' => 'Ausloggen', + 'ru' => 'Выйти', + ), + 'by' => + array ( + 'en' => 'by', + 'fr' => 'par', + 'de' => 'von', + 'ru' => 'сообщение', + ), + 'date_format' => + array ( + 'en' => '%1$s %2$s %3$s', + 'fr' => '%3$s %1$s %2$s', + 'de' => '%3$s %1$s %2$s', + 'ru' => '%1$s %2$s %3$s', + ), + 'ago' => + array ( + 'en' => 'ago', + 'fr' => 'il y a', + 'de' => 'Vor', + 'ru' => 'назад', + ), + 'to_go' => + array ( + 'en' => 'to go', + 'fr' => 'dans', + 'de' => 'In', + 'ru' => 'осталось', + ), + 'posted' => + array ( + 'en' => 'Posted', + 'fr' => 'Posté', + 'de' => 'Geschrieben', + 'ru' => 'Отправлено', + ), + 'error_auth' => + array ( + 'en' => 'Please press the Refresh button to display the homepage.', + 'fr' => 'Cliquez sur le bouton Rafraichir pour afficher la page d\'accueil.', + 'de' => 'Um auf die Hauptseite zu gelangen drücke bitte auf Aktualisieren.', + 'ru' => 'Для отображения домашней страницы нажмите кнопку "Обновить"', + ), + 'submit' => + array ( + 'en' => 'Submit', + 'fr' => 'Envoyer', + 'de' => 'Absenden', + 'ru' => 'Отправить', + ), + 'enter_key' => + array ( + 'en' => 'Please enter the full character API Key that you can find on your profile page', + 'fr' => 'Entrez la clé d\'API complète de votre personnage que vous trouverez sur votre page de profil', + 'de' => 'Gib bitte den lompletten Charakter-API-Schlüssel ein, diesen findest du auf deiner Profilseite', + 'ru' => 'Пожалуйста, введите полный API Ключ, который вы можете получить по адресу your profile page', + ), + 'enter_shard' => + array ( + 'en' => 'Select the server of your character', + 'fr' => 'Sélectionnez le serveur où se trouve votre personnage', + 'de' => 'Wähle den Server deines Charakters aus', + 'ru' => 'Выбрать сервер', + ), + 'enter_char' => + array ( + 'en' => 'Enter your CHARACTER name (*not* your account name)', + 'fr' => 'Saisissez le nom de votre PERSONNAGE (pas votre nom de compte)', + 'de' => 'Gib den Namen deines CHARAKTERS ein (*nicht* deinen Account-Namen)', + 'ru' => 'Введите имя ПЕРСОНАЖА (*не* имя пользователя)', + ), + 'enter_password' => + array ( + 'en' => 'Enter the password of your ACCOUNT', + 'fr' => 'Saisissez le mot de passe de votre COMPTE', + 'de' => 'Gib das Passwort deines ACCOUNTS ein', + 'ru' => 'Введите пароль своей УЧЕТНОЙ ЗАПИСИ', + ), + 'bad_login_password' => + array ( + 'en' => 'Cannot login. Perhaps you entered a bad password or you didn\'t use your CHARACTER name.', + 'fr' => 'Connexion impossible. Peut-être avez vous saisi un mauvais mot de passe ou vous n\'avez pas utilisé le nom de votre PERSONNAGE.', + 'de' => 'Login fehlgeschlagen. Vielleicht hast du ein falsches Passwort eingegeben oder du hast nicht deinen CHARAKTER-Namen verwendet.', + 'ru' => 'Невозможно подключиться. Возможно, вы использовали неверный пароль или имя ПЕРСОНАЖА.', + ), + 'app_notes' => + array ( + 'en' => 'Notepad', + 'fr' => 'Bloc Note', + 'de' => 'Notizblock', + 'ru' => 'Блокнот', + ), + 'app_news' => + array ( + 'en' => 'News', + 'fr' => 'Nouvelles', + 'de' => 'News', + 'ru' => 'Новости', + ), + 'app_mail' => + array ( + 'en' => 'Mail', + 'fr' => 'Courrier', + 'de' => 'Mail', + 'ru' => 'Почта', + ), + 'app_patch' => + array ( + 'en' => 'Atysmas', + 'fr' => 'Noel', + 'de' => 'Weihnachten', + 'ru' => 'Christmas', + ), + 'app_wiki' => + array ( + 'en' => 'Atys Wiki', + 'fr' => 'Lore & Chroniques', + 'de' => 'Atys Wiki', + 'ru' => 'Wiki Атиса', + ), + 'app_bots' => + array ( + 'en' => 'Bots', + 'fr' => 'Bots', + 'de' => 'Bots', + 'ru' => 'Боты', + ), + 'app_test' => + array ( + 'en' => 'Test Application', + 'fr' => 'Application de test', + 'de' => '', + 'ru' => '', + ), + 'app_forum' => + array ( + 'en' => 'Forums', + 'fr' => 'Forums', + 'de' => 'Foren', + 'ru' => 'Форумы', + ), + 'app_translate' => + array ( + 'en' => 'Translate', + 'fr' => 'Traduction', + 'de' => 'Übersetzen', + 'ru' => 'Перевод', + ), + 'app_race' => + array ( + 'en' => 'Race', + 'fr' => 'Course', + 'de' => 'Rennen', + 'ru' => 'Гонка', + ), + 'app_poll' => + array ( + 'en' => 'Polls', + 'fr' => 'Sondages', + 'de' => 'Polls', + 'ru' => 'Голосование', + ), + 'app_zapping' => + array ( + 'en' => 'Atysmas', + 'fr' => 'Atysmas', + 'de' => 'Atysmas', + 'ru' => 'Атисмас', + ), + 'latest_blog' => + array ( + 'en' => 'Latest news from the dev blog', + 'fr' => 'Dernières nouvelles du blog des dév', + 'de' => 'Aktuelles aus dem Dev-Blog', + 'ru' => 'Последние новости Дневника разработчиков', + ), + 'app_profile' => + array ( + 'en' => 'Profile', + 'fr' => 'Profil', + 'de' => 'Profile', + 'ru' => 'Личные данные', + ), + 'next_events' => + array ( + 'en' => 'Next events', + 'fr' => 'Prochains événements', + 'de' => 'Nächste Events', + 'ru' => 'Ближайшие события', + ), + 'absolute_date_format' => + array ( + 'en' => '%2$s, %1$s %3$s', + 'fr' => '%2$s %1$s %3$s', + 'de' => '%2$s %1$s %3$s', + 'ru' => '%2$s, %1$s %3$s', + ), + 'app_craft' => + array ( + 'en' => 'Craft: Recipe-Book', + 'fr' => 'Craft : Livre de recettes', + 'de' => 'Craft: Recipe-Book', + 'ru' => 'Ремесло: чертежи', + ), + 'app_ryzhome' => + array ( + 'en' => 'RyzHome', + 'fr' => 'Mon appart', + 'de' => 'Meine Wohnung', + 'ru' => 'Мой Дом', + ), + 'app_event' => + array ( + 'en' => 'Event Pad', + 'fr' => 'Pad Event', + 'de' => 'Event-Pad', + 'ru' => 'События', + ), + 'app_calendar' => + array ( + 'en' => 'Calendar', + 'fr' => 'Calendrier', + 'de' => 'Kalender', + 'ru' => 'Календарь', + ), + 'app_contest' => + array ( + 'en' => 'Contest', + 'fr' => 'Concours', + 'de' => 'Contest', + 'ru' => 'конкурс', + ), + 'app_rpjobs_v2' => + array ( + 'en' => 'Occupations', + 'fr' => 'Métiers', + 'de' => 'Berufe', + 'ru' => 'Занятия', + ), + 'app_rewards' => + array ( + 'en' => 'Rewards', + 'fr' => 'Récompenses', + 'de' => 'Belohnungen', + 'ru' => 'Награды', + ), + 'admin_apps' => + array ( + 'en' => 'Ryzom Team Apps', + 'fr' => 'Applications Pour L\'équipe Ryzom', + 'de' => 'Ryzom Team Apps', + 'ru' => 'Ryzom Team Apps', + ), + 'dev_apps' => + array ( + 'en' => 'Devs Apps (don\'t use!)', + 'fr' => 'Applications Devs (Ne pas utiliser !)', + 'de' => 'Devs Apps (don\'t use!)', + 'ru' => 'Devs Apps (don\'t use!)', + ), + 'app_admin' => + array ( + 'en' => 'Administration', + 'fr' => 'Administration', + 'de' => '{app_admin}', + 'ru' => '{app_admin}', + ), + 'testing_apps' => + array ( + 'en' => 'Testing Apps (don\'t use without permission)', + 'fr' => 'Applications en test (N\'utilisez que si vous y êtes invité)', + 'de' => 'Testing Apps (don\'t use without permission)', + 'ru' => 'Testing Apps (don\'t use without permission)', + ), + 'app_arcc' => + array ( + 'en' => 'A.R.C.C.', + 'fr' => 'A.R.C.C.', + 'de' => 'A.R.C.C.', + 'ru' => 'A.R.C.C.', + ), + 'link_to_forum' => + array ( + 'en' => 'Show details in forum', + 'fr' => 'Voir détails sur le forum', + 'de' => 'Zeige Details im Forum', + 'ru' => '', + ), + 'aura_and_powers_reseted' => + array ( + 'en' => 'Your auras and powers have been reset. They can be reset again in 2 hours.', + 'fr' => 'Vos auras et pouvoirs ont été remis à zéro. Prochaine remise à zéro dans 2h.', + 'de' => 'Deine Auren und Kräfte wurden zurückgesetzt. Sie können erst in 2 Stunden erneut zurückgesetzt werden.', + 'ru' => '', + ), + 'pvp_reseted' => + array ( + 'en' => 'Your PvP timers have been reset. ', + 'fr' => 'Votre tag pvp à été remis à zéro.', + 'de' => 'Deine PvP-Timer wurden zurückgesetzt.', + 'ru' => '', + ), + 'temporary_fixes' => + array ( + 'en' => 'Temporary Fixes', + 'fr' => 'Correctifs temporaires', + 'de' => 'Temporäre Fixes', + 'ru' => '', + ), + 'aura_and_powers_wait' => + array ( + 'en' => 'Please wait %d min for next reset', + 'fr' => 'Merci d\'attendre %d minutes avant une nouvelle remise à zéro', + 'de' => 'Please wait %d min for next reset', + 'ru' => '', + ), + 'app_power_reset' => + array ( + 'en' => 'Reset of Aura and Powers', + 'fr' => 'Reset des Auras et Pouvoirs', + 'de' => 'Auren und Kräfte zurücksetzen', + 'ru' => '', + ), +); +if(isset($ryzom_texts)) + $ryzom_texts = array_merge ($__texts, $ryzom_texts); +else + $ryzom_texts = $__texts;