Page MenuHomeCode

No OneTemporary

This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/content/scenes/B00001001.tpl b/content/scenes/B00001001.tpl
index 2a64460..1b5ad7c 100644
--- a/content/scenes/B00001001.tpl
+++ b/content/scenes/B00001001.tpl
@@ -1,156 +1,158 @@
<!-- Tower navigation and passage CSS -->
<style>
body {
overflow: hidden;
}
/* Tower map */
#tower {
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/all.png);
background-position: left;
background-repeat: no-repeat;
height: 442px;
}
#tower_hl {
position: relative;
}
/* Passage */
#passage {
width: 960px;
height: 401px;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/bay/void.png);
background-position: top left;
background-repeat: no-repeat;
}
#passage_left {
position: relative;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/GoLeft.png);
width: 38px;
height: 38px;
}
#passage_right {
position: relative;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/GoRight.png);
width: 38px;
height: 38px;
}
#passage_gallery ul {
position: relative;
top: 145px;
left: 120px;
margin-top: inherit;
margin-bottom: inherit;
}
#passage_gallery li {
display: block;
float: left;
margin-right: 60px;
width: 170px;
height: 170px;
padding: 4px 4px;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/frame.png);
background-repeat: no-repeat;
background-position: top left;
}
#screen {
position: absolute;
left: 10%;
top: 10%;
width: 80%;
height: 80%;
}
#screen img {
position: absolute;
cursor: pointer;
visibility: hidden;
width: 0px;
height: 0px;
}
#screen .tvover {
border: solid #343434;
opacity: 1;
filter: alpha(opacity=100);
}
#screen .tvout {
border: solid #fff;
opacity: 0.7;
}
#bankImages {
display: none;
}
</style>
+ <!-- Javascript bits: dojo -->
+ <script>
+ dojo.require("dojo.parser");
+ dojo.require("dijit.Dialog");
+ dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.TextBox");
+ </script>
+
<!-- Tower -->
<!--
<div id="tower"></div>
-->
<!-- Passage -->
<div class="grid_16 alpha omega">
<div id="passage">
<div id="passage_gallery"></div>
</div>
</div>
<!-- Upload dialog -->
<div dojoType="dijit.Dialog" id="uploadDialog" style="display: none;" title="{#UploadNewArtwork#}">
<p>{#UploadNewArtworkDescription#}</p>
- <form method="post" id="test" action="{get_xhr_hashed_url('upload_content', {$CurrentPerso->location_global})}" enctype="multipart/form-data">
+ <form method="post" id="test" action="{get_xhr_hashed_url('upload_content', {$CurrentPerso->location_global})}?redirectTo={get_url()}" enctype="multipart/form-data">
<input type="hidden" id="location_local" name="location_local" value='{$CurrentPerso->location_local}' />
<input type="hidden" id="i" name="location_k" value="-1">
<div class="row">
<label for="artwork" class="firstLabel">{#UploadNewArtworkPicture#} (max. {ini_get('upload_max_filesize')})</label>
<input type="file" name="artwork" id="artwork" class="long" />
</div>
<div class="row">
<label for="title" class="firstLabel">{#UploadNewArtworkTitle#}</label>
<input dojoType="dijit.form.TextBox" name="title" id="title" type="text" class="long" />
</div>
<div class="row center">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />OK</button>
</div>
</form>
</div>
<!-- Javascript bits: script.aculo.us -->
<script src="{#StaticContentURL#}/js/prototype.js"></script>
<script src="{#StaticContentURL#}/js/effects.js"></script>
- <!-- Javascript bits: dojo -->
- <script>
- dojo.require("dojo.parser");
- dojo.require("dijit.Dialog");
- dojo.require("dijit.form.Button");
- dojo.require("dijit.form.TextBox");
- </script>
+
<!-- Javascript bits: tower and couloir/passage/corridor/gallery/whatNameYouGiveToIt -->
<script src="{$SCENE_URL}/{$CurrentPerso->location_global}/tower.js"></script>
<script>
//Initializes tower map
//tower.hl = '{$SCENE_URL}/{$CurrentPerso->location_global}/hl.png';
//tower.highlight(3);
//Initializes passage view
passage.bayPath = '{$SCENE_URL}/{$CurrentPerso->location_global}/couloir/bay/';
passage.initialize('{$location->global}', '{$CurrentPerso->location_local}');
//Initializes gallery
gallery.initialize('{#StaticContentURL#}', '{get_xhr_hashed_url('get_content', {$CurrentPerso->location_global})}');
</script>
\ No newline at end of file
diff --git a/css/zed/forms.css b/css/zed/forms.css
index 5411dd3..34c58fd 100644
--- a/css/zed/forms.css
+++ b/css/zed/forms.css
@@ -1,84 +1,97 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: forms.css
- Version: 1.0
+ Version: 1.1
Created: 2010-01-27
- Updated: 2010-01-27
+ Updated: 2010-07-02
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
-/* ------
+/* -------------------------------------------------------------
Import dojo CSS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@import "/js/dojo/dijit/themes/tundra/tundra.css";
/* -------------------------------------------------------------
Forms rows
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-form .row {
+form {
+ color: black;
+}
+
+form div.row {
margin-bottom: 0.8em;
}
hr {
width: 90%;
color: lightgray;
margin: 2em auto 2em auto;
}
/* -------------------------------------------------------------
input tags width
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.small {
width: 5em;
}
.medium {
width: 12em;
}
.long {
width: 20em;
}
/* -------------------------------------------------------------
Labels (from dojo CSS)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+label {
+ color: white;
+}
+
.firstLabel {
display: inline-block;
display: -moz-inline-box;
width: 10em;
min-width: 10em;
vertical-align: top;
}
.secondLabel {
width: auto;
margin-left: 5em;
margin-right: 1em;
}
fieldset label {
margin-right: 1em;
}
/* -------------------------------------------------------------
Misc
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Doesn't display DOJO tooltips provider if JS disabled */
.dojotooltip {
display: none;
}
-.dijitButton {
- color: black;
+/* Kludge: normal font size for form items */
+form {
+ font-size: 90%;
}
+
+label {
+ font-size: medium;
+}
\ No newline at end of file
diff --git a/css/zed/profile.css b/css/zed/profile.css
index 954914b..0f1aae7 100644
--- a/css/zed/profile.css
+++ b/css/zed/profile.css
@@ -1,116 +1,124 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: profile.css
Version: 1.0
Created: 2010-01-27
Updated: 2010-02-11
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
/* -------------------------------------------------------------
Profile header
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.profile_id {
height: 40px;
line-height: 1.2em;
background-color: black;
color: white;
}
.profile_id H1 {
color: #04acf8;
}
.profile_info {
float: right;
font-size: 0.90em;
padding-right: 1em;
}
.profile_info a {
color: white;
}
.profile_info a:hover {
color: white;
font-weight: bold;
}
.profile_nick {
float: left;
margin-top: 0;
height: 30px;
padding-left: 12px;
padding-top: 10px;
font-size: 1.25em;
font-weight: 500;
border-left: solid #04acf8 6px;
}
/* -------------------------------------------------------------
Profile
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.profile {
background-color: black;
color: white;
margin-bottom: 20px;
border: 2px solid #04acf8;
}
.profile_text {
margin-left: 10px;
margin-right: 10px;
padding-top: 1em;
font-size: 1em;
text-align: justify;
}
.profile_text img {
border: 0px;
}
.profile_text.fixedwidth {
font-family: Fixedsys, Fixed;
white-space: pre;
}
/* -------------------------------------------------------------
Profile comments
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.profile_comments {
background-color: #fafafa;
border: solid 1px #dedede;
}
.profile_comments_info {
font-style: italic;
}
.profile_comments_text {
font-size: 1.25em;
}
/* -------------------------------------------------------------
Profile editor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.photos {
}
.photo img {
margin: 8px 0px 12px 20px;
border: 0;
}
.photo {
float: left;
-}
\ No newline at end of file
+}
+
+/* -------------------------------------------------------------
+ Profile sidebar
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#sidebar {
+ color: white;
+}
diff --git a/css/zed/theme.css b/css/zed/theme.css
index 11e57e8..d7c95b1 100644
--- a/css/zed/theme.css
+++ b/css/zed/theme.css
@@ -1,418 +1,416 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: theme.css
- Version: 1.0
+ Version: 1.1
Created: 2010-01-27
- Updated: 2010-01-27
+ Updated: 2010-07-02
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
/* -------------------------------------------------------------
Page settings
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
body {
margin: 0.5em 0 0 0;
background-attachment: fixed;
background-color: #343434;
background-image: url("../../img/zed/bg.jpg");
background-position: top left;
background-repeat: no-repeat;
font-family: "Calibri", "Lucida Sans Unicode", "Trebuchet MS", "Helvetica", "Arial", sans-serif;
min-height: 1200px;
}
.container_16 {
color: white;
}
-#content {
- width: 980px;
- background-image: url("../../img/zed/bg_content.jpg");
- background-position: top left;
- background-repeat: no-repeat;
-}
-
-
h1 {
color: #19B5E7;
font-size: 21px;
font-weight: normal;
}
h2, h3, h4, h5, h6 {
color: #04acf8;
font-weight: normal;
}
h2 {
font-size: 19px;
}
h3 {
color: #04acf8;
font-size: 16px;
}
pre {
font-family: FixedSys, monospace;
}
/* -------------------------------------------------------------
Links
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a {
color: #1AC8E8;
text-decoration: none;
}
a:visited {
color: gray;
}
a:hover {
color: red;
text-decoration: none;
}
/* -------------------------------------------------------------
Notify messages
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.notify {
padding-top: 25px;
padding-bottom: 25px;
margin-bottom: 10px;
text-align: center;
background: #eeeeee;
font-size: 1.5em;
color: black;
border: 5px solid #1AC8E8;
width: 950px;
}
.wap {
padding-top: 50px;
padding-bottom: 50px;
margin-bottom: 10px;
text-align: center;
background: #eeeeee;
font-size: 2em;
color: black;
border: 5px solid indianred;
width: 950px;
}
/* -------------------------------------------------------------
Header
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#header {
background-image: url("../../img/zed/bg_header.png");
background-repeat: no-repeat;
margin: auto auto;
margin-bottom: 0.5em;
height: 104px;
width: 978px;
}
#header_content {
padding-top: 26px;
}
#HypershipTime {
color: white;
font-size: 0.8em;
background-image: url("../../img/zed/time.png");
background-position: center left;
background-repeat: no-repeat;
text-indent: 2em;
}
/* -------------------------------------------------------------
Header - wall
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.wall {
text-align: left;
float:left;
color: white;
font-size: 0.8em;
background-image: url("../../img/zed/quote.png");
background-position: top left;
background-repeat: no-repeat;
text-indent: 2em;
margin-bottom: 0.8em;
}
.wall_info {
display: block;
text-align: right;
/* font-size: 80%; */
}
.wall a {
color: #a9a49e;
}
.wall a:hover {
color: #fd9800;
}
/* -------------------------------------------------------------
Content (e.g. stories in /explore)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.content_wrapper {
background-color: #171717;
border: solid 5px black;
margin-bottom: 1em;
}
.content_wrapper .content {
padding: 0 2em 0 2em;
+ color: white;
}
.content_wrapper H1 {
margin-top: 0;
padding: 0.25em 0 0.75em 1em;
background-color: black;
height: 1em;
}
/* -------------------------------------------------------------
Avatars wall
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.avatar {
float: left;
margin-bottom: 2em;
margin-right: 2em;
text-align: center;
}
+.avatar img {
+ border: solid 1px;
+}
+
.avatar_name {
display: block;
}
.avatar a:hover {
- color: white;
+ color: white;
}
/* -------------------------------------------------------------
Messages
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.message {
margin-bottom: 17px;
padding: 8px 9px 8px 9px;
width: 940px;
font-size: 80%;
}
.message.light {
background-color: #fafafa;
border: 3px solid #dedede;
width: 938px;
color: black;
}
.message.light a {color: #343434;}
.message.dark {
background-color: #acc0c3;
border: solid 3px #4e5758;
width: 938px;
color: #000033;
}
.message.dark a {color: #154c4c;}
.message a:hover {
font-weight: 900;
}
.message_info {
text-align: right;
margin-bottom: 1em;
}
.message_text {
font-size: 1.25em;
}
.message_info {
color: #343434;
}
/* -------------------------------------------------------------
Helper classes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.center {
text-align: center;
}
/* -------------------------------------------------------------
Color boxes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.plum {
background-color: plum;
border: 1px solid #800080;
color: black;
}
.plum a { color: #800080; }
.green {
background-color: beige;
border: 1px solid darkgreen;
color: black;
}
.green a { color: darkgreen; }
.skyblue {
background-color: lightskyblue;
border: 1px solid #6e47fe;
}
.skyblue a { color:navy }
.indigo {
background-color: #AE97E1;
border: 1px solid #C97FFF;
}
.indigo a {color: #800080;}
.yellow {
background-color: #FFFFCC;
border: 1px solid #C4B963;
}
.yellow a {color: navy;}
.orange {
background-color: #FDD9AC;
border: 1px solid #eaaf67;
}
.orange a {color: #43392e;}
.red {
background-color: #FFE4E1;
border: solid 1px #DC7777;
}
.red a {color: #993333;}
.black {
background-color: black;
color: #ccc;
border: solid 2px #555;
}
.plum a:hover,
.green a:hover,
.skyblue a:hover,
.indigo a:hover,
.yellow a:hover,
.orange a:hover,
.red a:hover{
font-weight: bold;
}
/* -------------------------------------------------------------
SmartLine
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#SmartLine {
width: 100%;
}
#SmartLine .left {
}
#SmartLine .right {
float: right;
text-align: right;
}
/* TODO: ajouter un sélecteur de SmarLine pour chat/commandes (60px) */
/* grid_1 alpha -> sélecteur, grid_3 -> history, grid_12 > bar */
#SmartLineHistory {
width: 115%; /* dépasse de sa bordure */
}
#SmartLineBar{
/* 99.6% for alignment with .message.light */
width: 99.6%;
}
#SmartLineResults {
font-family: "Fixedsys Excelsior 3.01", FixedSys, Terminal;
font-size: 12pt;
}
#SmartLineResults .highlight {
color: #16c3cc;
}
#SmartLineResults .error {
color: red;
}
#SmartLineResults p {
padding-left: 1em;
}
/* -------------------------------------------------------------
Floating panes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.floatingPaneTutorial {
width: 957.5px;
margin-bottom: 1em;
color: black;
}
.floatingPaneTutorial a {
color: navy;
}
.floatingPaneTutorial a:hover {
color: #5f0505;
}
.floatingPaneTutorial p {
color: black;
margin: 0;
padding: 5px 10px 0px 10px;
}
.dojoxDockList {
color: black;
}
/* -------------------------------------------------------------
Footer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#footer {
font-size: 80%;
+ color: white;
}
\ No newline at end of file
diff --git a/includes/SmartLine/ZedCommands.php b/includes/SmartLine/ZedCommands.php
index 8f9be67..0a011b5 100644
--- a/includes/SmartLine/ZedCommands.php
+++ b/includes/SmartLine/ZedCommands.php
@@ -1,234 +1,264 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* SmartLine
*
*/
///
/// Register commands
///
$smartLine->register_object('goto', 'GotoSmartLineCommand');
$smartLine->register_object('guid', 'GUIDSmartLineCommand');
+$smartLine->register_object('invite', 'InviteSmartLineCommand');
+$smartLine->register_object('invites', 'InviteSmartLineCommand');
$smartLine->register_object('list', 'ListSmartLineCommand');
$smartLine->register_object('unixtime', 'UnixTimeSmartLineCommand');
$smartLine->register_object('requests', 'RequestsSmartLineCommand');
$smartLine->register_object('whereami', 'WhereAmISmartLineCommand');
///
/// Help (todo: move $lang array in lang folder)
///
$lang['Help']['goto'] = "Go to a location";
$lang['Help']['guid'] = "Generate a GUID";
$lang['Help']['list'] = "Lists specified objects (bodies, locations or places)";
$lang['Help']['requests'] = "Checks if there are waiting requests";
$lang['Help']['unixtime'] = "Prints current unixtime (seconds elapsed since 1970-01-01 00:00, UTC) or the specified unixtime date.";
$lang['Help']['whereami'] = "Where am I?";
+$lang['Help']['invite'] = "Generate an invite. To see the generated invites, invite list.";
///
/// whereami
///
class WhereAmISmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
global $CurrentPerso;
require_once("includes/geo/location.php");
$place = new GeoLocation($CurrentPerso->location_global);
$this->SmartLine->puts($CurrentPerso->location_global . ' - ' . $place);
}
}
///
/// GUID
///
class GUIDSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
if ($argc > 1 && is_numeric($argv[1])) {
for ($i = 0 ; $i < $argv[1] ; $i++) {
$this->SmartLine->puts(new_guid());
}
return;
}
$this->SmartLine->puts(new_guid());
}
}
///
/// Requests
///
class RequestsSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
global $CurrentPerso;
$force = ($argc > 1) && ($argv[1] == "-f" || $argv[1] == "--force");
if ($force || (array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests'])) {
global $controller;
$controller = 'controllers/persorequest.php';
} else {
$this->SmartLine->puts("No request waiting.");
}
}
}
///
/// goto
///
class GotoSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
global $CurrentPerso;
if ($argc == 1) {
$this->SmartLine->puts("Where do you want to go?", STDERR);
return;
}
require_once("includes/geo/location.php");
try {
$place = new GeoLocation($argv[1]);
} catch (Exception $ex) {
$this->SmartLine->puts($ex->getMessage(), STDERR);
return;
}
if ($place->equals($CurrentPerso->location_global)) {
$this->SmartLine->puts("You're already there.");
return;
}
if (!$place->exists()) {
$this->SmartLine->puts("This place doesn't seem to exist.");
return;
}
$this->SmartLine->puts("TODO: code travel assistant");
}
}
///
/// list
///
class ListSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
if ($argc == 1) {
$this->SmartLine->puts("Available lists: bodies, locations, places");
return;
}
switch ($objects = $argv[1]) {
case 'bodies':
$list = $this->get_list(TABLE_BODIES, "CONCAT('B', body_code)", "body_name");
$this->SmartLine->puts($list);
break;
case 'locations':
$list = $this->get_list(TABLE_LOCATIONS, "location_code", "location_name");
$this->SmartLine->puts($list);
break;
case 'places':
if ($argv[2] == "-a" || $argv[2] == "--all") {
//Global bodies places list
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name");
} else {
//Local places (or equivalent) list
global $CurrentPerso;
switch ($CurrentPerso->location_global[0]) {
case 'B':
$body_code = substr($CurrentPerso->location_global, 1, 5);
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name", "body_code = $body_code");
break;
case 'S':
$this->SmartLine->puts("I don't have a map of the spaceship.", STDERR);
return;
default:
$this->SmartLine->puts("Unknown location type. Can only handle B or S.", STDERR);
return;
}
}
$this->SmartLine->puts($list);
break;
default:
$this->SmartLine->puts("Unknown objects to list: $objects", STDERR);
}
}
public function get_list ($table, $key, $value, $where = null) {
global $db;
$sql = "SELECT $key as `key`, $value as value FROM $table ";
if ($where) $sql .= "WHERE $where ";
$sql .= "ORDER BY `key` ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to fetch list", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$rows .= "<tr><td>$row[key]</td><td>$row[value]</td></tr>";
}
$this->SmartLine->truncate(STDERR);
return "<table cellspacing=\"8\"><thead style=\"color: white\" scope=\"row\"><tr><th>Key</th><th>Value</th></thead><tbody>$rows</tbody></table>";
}
}
///
/// unixtime
///
class UnixTimeSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
date_default_timezone_set('UTC');
if ($argc == 1) {
$this->SmartLine->puts(time());
} elseif ($argc == 2 && is_numeric($argv[1])) {
$this->SmartLine->puts(strftime("%Y-%m-%d %X", $argv[1]));
} else {
array_shift($argv);
$date = implode(' ', $argv);
if ($time = strtotime($date) !== false) {
$this->SmartLine->puts("Unixtime from $date: <span class=\"highlight\">$time</span>");
} else {
$this->SmartLine->puts("$date isn't a unixtime nor a valid date strtotime is able to parse.", STDERR);
}
}
}
}
///
/// invite
///
class InviteSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
- require_once
- //Checks if we could invite
- date_default_timezone_set('UTC');
- if ($argc == 1) {
- $this->SmartLine->puts(time());
- } elseif ($argc == 2 && is_numeric($argv[1])) {
- $this->SmartLine->puts(strftime("%Y-%m-%d %X", $argv[1]));
- } else {
- array_shift($argv);
- $date = implode(' ', $argv);
- if ($time = strtotime($date) !== false) {
- $this->SmartLine->puts("Unixtime from $date: <span class=\"highlight\">$time</span>");
+ require_once('includes/objects/invite.php');
+ global $CurrentUser, $CurrentPerso;
+
+ $command = ($argc > 1) ? strtolower($argv[1]) : '';
+ switch ($command) {
+ case 'list':
+ $codes = Invite::get_invites_from($CurrentPerso->id);
+ if (!count($codes)) {
+ $this->SmartLine->puts("No invite code.");
} else {
- $this->SmartLine->puts("$date isn't a unixtime nor a valid date strtotime is able to parse.", STDERR);
+ foreach ($codes as $code) {
+ $this->SmartLine->puts($code);
+ }
}
+ break;
+
+ case 'add':
+ case '':
+ $code = Invite::create($CurrentUser->id, $CurrentPerso->id);
+ $url = get_server_url() . get_url('invite', $code);
+ $this->SmartLine->puts("New invite code created: $code<br />Invite URL: $url");
+ break;
+
+ case 'del':
+ $code = $argv[2];
+ if (!preg_match("/^([A-Z]){3}([0-9]){3}$/i", $code)) {
+ $this->SmartLine->puts("Invalid code format. Use invite list to get all your invite codes.", STDERR);
+ } else {
+ $invite = new Invite($code);
+ if ($CurrentPerso->id == $invite->from_perso_id) {
+ $invite->delete();
+ $this->SmartLine->puts("Deleted");
+ } else {
+ $this->SmartLine->puts("Invalid code. Use invite list to get all your invite codes.", STDERR);
+ }
+ }
+ break;
+
+ default:
+ $this->SmartLine->puts("Usage: invite [add|list|del <code>]", STDERR);
+ break;
}
+
}
}
?>
\ No newline at end of file
diff --git a/includes/config.php b/includes/config.php
index 7370b37..c6937fd 100644
--- a/includes/config.php
+++ b/includes/config.php
@@ -1,181 +1,182 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* Autogenerable configuration file
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// I. SQL configuration ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//SQL configuration
$Config['sql']['product'] = 'MySQL'; //Only MySQL is currently implemented
$Config['sql']['host'] = 'localhost';
$Config['sql']['username'] = 'zed';
$Config['sql']['password'] = 'zed';
$Config['sql']['database'] = 'zed';
//SQL tables
$prefix = '';
define('TABLE_API_KEYS', $prefix . 'api_keys');
define('TABLE_COMMENTS', $prefix . 'comments');
define('TABLE_LOG', $prefix . 'log');
define('TABLE_LOG_SMARTLINE', $prefix . 'log_smartline');
define('TABLE_MESSAGES', $prefix . 'messages');
define('TABLE_MOTD', $prefix . 'motd');
define('TABLE_PAGES', $prefix . 'pages');
define('TABLE_PAGES_EDITS', $prefix . 'pages_edits');
define('TABLE_PERSOS', $prefix . 'persos');
define('TABLE_PERSOS_FLAGS', $prefix . 'persos_flags');
define('TABLE_PERSOS_NOTES', $prefix . 'persos_notes');
+define('TABLE_PORTS', $prefix . 'ports');
define('TABLE_PROFILES', $prefix . 'profiles');
define('TABLE_PROFILES_COMMENTS', $prefix . 'profiles_comments');
define('TABLE_PROFILES_PHOTOS', $prefix . 'profiles_photos');
define('TABLE_REGISTRY', $prefix . 'registry');
define('TABLE_SESSIONS', $prefix . 'sessions');
define('TABLE_SHIPS', $prefix . 'ships');
define('TABLE_USERS', $prefix . 'users');
define('TABLE_USERS_INVITES', $prefix . 'users_invites');
define('TABLE_USERS_OPENID', $prefix . 'users_openid');
//Geo tables
define('TABLE_BODIES', $prefix . 'geo_bodies');
define('TABLE_LOCATIONS', $prefix . 'geo_locations'); //Well... it's a view
define('TABLE_PLACES', $prefix . 'geo_places');
////////////////////////////////////////////////////////////////////////////////
/// ///
/// II. Site configuration ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Default theme
$Config['DefaultTheme'] = "Zed";
//Dates
date_default_timezone_set("UTC");
//Secret key, used for some verification hashes in URLs or forms.
$Config['SecretKey'] = 'Je balaye les petits ewoks comme le vent balaye les feuilles mortes';
//When reading files, buffer size
define('BUFFER_SIZE', 4096);
////////////////////////////////////////////////////////////////////////////////
/// ///
/// III. Script URLs ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Without mod_rewrite:
*
* Subdirectory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership/index.php';
* - $Config['BaseURL'] = '/hypership/index.php';
*
* Root directory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/index.php';
* - $Config['BaseURL'] = '/index.php';
*
* With mod_rewrite:
*
* Subdirectory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership';
* - $Config['BaseURL'] = '/hypership';
*
* In .htaccess or your vhost definition:
* RewriteEngine On
* RewriteBase /hypership/
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteCond %{REQUEST_FILENAME} !-d
* RewriteRule . /hypership/index.php [L]
*
* Root directory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be';
* - $Config['BaseURL'] = '';
*
* In .htaccess or your vhost definition:
* RewriteEngine On
* RewriteBase /
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteCond %{REQUEST_FILENAME} !-d
* RewriteRule . /index.php [L]
*
*
* If you don't want to specify the server domain, you can use get_server_url:
* $Config['SiteURL'] = get_server_url() . '/hypership';
* $Config['SiteURL'] = get_server_url();
*
* !!! No trailing slash !!!
*
*/
$Config['SiteURL'] = get_server_url();
$Config['BaseURL'] = '';
//AJAX callbacks URL
$Config['DoURL'] = $Config['SiteURL'] . "/do.php";
////////////////////////////////////////////////////////////////////////////////
/// ///
/// IV. Static content ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Where the static content is located?
//Static content = 4 directories: js, css, img and content
//On default installation, those directories are at site root.
//To improve site performance, you can use a CDN for that.
//To use
//
//Recommanded setting: $Config['StaticContentURL'] = $Config['SiteURL'];
//Or if Zed is the site root: $Config['StaticContentURL'] = '';
//With CoralCDN: $Config['StaticContentURL'] = . '.nyud.net';
//
$Config['StaticContentURL'] = '';
//$Config['StaticContentURL'] = get_server_url() . '.nyud.net';
//Scenes
define('SCENE_DIR', 'content/scenes');
define('SCENE_URL', $Config['StaticContentURL'] . '/' . SCENE_DIR);
//Stories
define('STORIES_DIR', "content/stories");
//Profile's photos
define('PHOTOS_DIR', 'content/users/_photos');
define('PHOTOS_URL', $Config['StaticContentURL'] . '/' . PHOTOS_DIR);
//ImageMagick paths
//Be careful on Windows platform convert could match the NTFS convert command.
$Config['ImageMagick']['convert'] = 'convert';
$Config['ImageMagick']['mogrify'] = 'mogrify';
$Config['ImageMagick']['composite'] = 'composite';
$Config['ImageMagick']['identify'] = 'identify';
////////////////////////////////////////////////////////////////////////////////
/// ///
/// V. Sessions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Sessions
//If you want to use a common table of sessions / user handling
//with several websites, specify a different resource id for each site.
$Config['ResourceID'] = 21;
//PHP variables
ini_set('session.serialize_handler', 'wddx');
ini_set('session.save_path', 'cache/sessions');
ini_set('session.gc_maxlifetime', 345600); //4 days, for week-end story pause and continue url
?>
\ No newline at end of file
diff --git a/includes/login.php b/includes/login.php
index 04326d3..7cf45e8 100644
--- a/includes/login.php
+++ b/includes/login.php
@@ -1,123 +1,122 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* Login/logout
*/
if (!file_exists('/dev/urandom')) {
//We're on Windows, without reliable source of random numbers
define('Auth_OpenID_RAND_SOURCE', null);
}
//require_once('Auth/OpenID/Consumer.php');
//require_once('Auth/OpenID/DumbStore.php');
//require_once('Auth/OpenID/FileStore.php');
/*
function get_openid_consumer () {
if (!file_exists('/dev/urandom')) {
//We're on Windows, without reliable source of random numbers
define('Auth_OpenID_RAND_SOURCE', null);
}
$fs = new Auth_OpenID_FileStore('cache/openid');
return new Auth_OpenID_Consumer($fs);
}
*/
function openid_login ($url) {
global $db, $_SESSION, $LoginError, $LoginSuccessful;
$url = $db->sql_escape($url);
$sql = 'SELECT user_id FROM ' . TABLE_USERS_OPENID
. " WHERE openid_url LIKE '$url'";
if ($user_id = $db->sql_query_express($sql)) {
$sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id LIKE '$_SESSION[ID]'";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la connexion", '', __LINE__, __FILE__, $sql);
$LoginSuccessful = true;
setcookie("LastOpenID", $url, time() + 2592000);
header("location: " . get_url());
} else {
$LoginError = "To join Zed, you need an invite. Read the source to get one.";
}
}
if ($_GET['action'] == 'openid.login') {
$LoginError = "OpenID temporarily disabled.";
/*
//Gets Auth_OpenID_Consumer instance
$fs = new Auth_OpenID_DumbStore("rien n'est sûr mais c'est une piste");
//$fs = new Auth_OpenID_FileStore('cache/openid');
$consumer = new Auth_OpenID_Consumer($fs);
//$consumer = get_openid_consumer();
//Completes the OpenID transaction
$reply = $consumer->complete(get_server_url() . $_SERVER['REQUEST_URI']);
if ($reply->status == Auth_OpenID_SUCCESS) {
openid_login($reply->endpoint->claimed_id);
} elseif ($reply->message) {
$LoginError = "[OpenID] $reply->message";
} else {
$LoginError = "[OpenID] $reply->status";
}
*/
} elseif ($_POST['LogIn']) {
//User have filled login form
if ($_POST['openid']) {
$LoginError = "OpenID temporarily disabled.";
/*
//Gets Auth_OpenID_Consumer instance
$fs = new Auth_OpenID_DumbStore("rien n'est sûr mais c'est une piste");
//$fs = new Auth_OpenID_FileStore('cache/openid');
$consumer = new Auth_OpenID_Consumer($fs);
//$consumer = get_openid_consumer();
//Starts the OpenID transaction and redirects user to provider url
if ($request = $consumer->begin($_POST['openid'])) {
$url = $request->redirectURL(get_server_url(), "$Config[SiteURL]/?action=openid.login", false);
header("location: $url");
$LoginError = '<a href="' . $url . '">Click here to continue login</a>';
} else {
$LoginError = 'Invalid OpenID URL.';
}
*/
} else {
//GESTION LOGIN
$Login = $_POST['username'];
$sql = "SELECT user_password, user_id FROM " . TABLE_USERS . " WHERE username = '$Login'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Impossible d'interroger le listing des utilisateurs", '', __LINE__, __FILE__, $sql);
if ($row = $db->sql_fetchrow($result)) {
if (!$row['user_password']) {
$LoginError = "This account exists but haven't a password defined. Use OpenID or contact dereckson (at) espace-win.org to fix that.";
} elseif ($row['user_password'] != md5($_POST['password'])) {
//PASS NOT OK
$LoginError = "Incorrect password.";
} else {
- $sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$row[user_id]' WHERE session_id LIKE '$_SESSION[ID]'";
- if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la connexion", '', __LINE__, __FILE__, $sql);
+ login($row[user_id], $Login);
$LoginSuccessful = true;
- setcookie("LastUsername", $Login, time() + 2592000);
}
} else {
//Idiot proof facility
//Redirects people using login page as invitation claim page
- $sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_for = '$Login'";
+ $code = $db->sql_escape($_POST['password']);
+ $sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$code'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get invites", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
- $url = get_url('invite', $Login, $_POST['password']);
+ $url = get_url('invite', $_POST['password']);
header('location: ' . $url);
}
//Login not found
$LoginError = "Login not found.";
}
}
} elseif ($_POST['LogOut'] || $_GET['action'] == "user.logout") {
Logout();
}
?>
diff --git a/includes/objects/content.php b/includes/objects/content.php
index 911250b..224dfeb 100644
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,270 +1,268 @@
<?php
/*
* Content class
*
* 0.1 2010-02-24 15:57 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @copyright Copyright (c) 2010, Dereckson
* @license Released under BSD license
* @version 0.1
* @todo remove dbc temporary limitations (cf. /do.php upload_content and infra)
* @todo create a class ContentLocation and move location fields there
* @todo validate SQL schema and add in config.php TABLE_CONTENT tables
*
* [DESIGN BY CONTRACT] This class works only with the following assertions:
* i. Each content have EXACTLY ONE location
* ii. Location fields will not be modified
*
* If a content have more than one location, only the first occurence in
* content_locations table will be considered.
*
* If a content have no location, it will be ignored.
*
* If you edit content location, then call saveToDatabase, you will create
* a new location but future instances will contain first not deleted location.
*
*/
class Content {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $id;
public $path;
public $user_id;
public $perso_id;
public $title;
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $perso_name;
public $perso_nickname;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Initializes a new Content instance
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/*
* Returns a string representation of current Content instance
* @return string the content title or path if title is blank.
*/
function __toString () {
return $this->title ? $this->title : $this->path;
}
/* -------------------------------------------------------------
Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Loads the object Content (ie fill the properties) from the $_POST array
* @param boolean $allowSensibleFields if false, allow only location_local, location_k and title to be defined ; otherwise, allow all fields.
*/
function load_from_form ($allowSensibleFields = false) {
if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('location_k', $_POST)) $this->location_k = $_POST['location_k'];
if ($allowSensibleFields) {
if (array_key_exists('path', $_POST)) $this->path = $_POST['path'];
if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
}
}
/*
* Loads the object Content (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM content WHERE content_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Content unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/*
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
if (array_key_exists('perso_name', $row)) $this->perso_name = $row['perso_name'];
if (array_key_exists('perso_nickname', $row)) $this->perso_nickname = $row['perso_nickname'];
}
/*
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
$location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
$location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
//Saves location
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Determines if the extension is valid
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/*
* Creates a directory
*/
function create_directory ($dir) {
if (!file_exists($dir)) {
@mkdir($dir); //Creates new directory, chmod 777
}
}
/*
* @return boolean true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
/*
* Generates a thumbnail using ImageMagick binary
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
//Builds thumbnail filename
$sourceFile = $this->path;
$pos = strrpos($this->path, '.');
$thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
//Executes imagemagick command
- $command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
- echo "$command";
- system($command, $code);
+ @system($command, $code);
//Returns true if the command have exited with errorcode 0 (= ok)
return ($code == 0);
}
/* -------------------------------------------------------------
Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Gets content at specified location
* @param string $location_global global content location
* @param string $location_local local content location
* @return Array array of Content instances
*/
static function get_local_content ($location_global, $location_local) {
global $db;
//Get contents at this location
$location_global = $db->sql_escape($location_global);
$location_local = $db->sql_escape($location_local);
$sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
//Fills content array
$contents = array();
while ($row = $db->sql_fetchrow($result)) {
$content = new Content();
$content->load_from_row($row);
$contents[] = $content;
}
return $contents;
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/port.php b/includes/objects/port.php
index 6ef5466..01f36b4 100644
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,176 +1,176 @@
<?php
/*
* Port class
*
* 0.1 2010-02-09 19:17 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @copyright Copyright (c) 2010, Dereckson
* @license Released under BSD license
* @version 0.1
*
*/
class Port {
public $id;
public $location_global;
public $location_local;
public $name;
public $hidden;
public $requiresPTA;
public $default;
/*
* Initializes a new instance
* @param int $id the primary key
*/
- function __construct ($id = null) {
+ function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/*
* Loads the object Port (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('hidden', $_POST)) $this->hidden = $_POST['hidden'] ? true : false;
if (array_key_exists('requiresPTA', $_POST)) $this->requiresPTA = $_POST['requiresPTA'] ? true : false;
if (array_key_exists('default', $_POST)) $this->hidden = $_POST['default'] ? true : false;
}
/*
* Loads the object Port (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
- $sql = "SELECT * FROM ports WHERE port_id = '" . $id . "'";
+ $sql = "SELECT * FROM " . TABLE_PORTS . " WHERE port_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ports", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Port unkwown: " . $this->id;
return false;
}
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->name = $row['port_name'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['port_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
/*
* Gets status field value
*/
function get_status () {
$flags = array('hidden', 'requiresPTA', 'default');
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
/*
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$name = $db->sql_escape($this->name);
$status = $this->get_status();
//Updates or inserts
- $sql = "REPLACE INTO ports (`port_id`, `location_global`, `location_local`, `port_name`, `port_status`) VALUES ($id, '$location_global', '$location_local', '$name', '$status')";
+ $sql = "REPLACE INTO " . TABLE_PORTS . " (`port_id`, `location_global`, `location_local`, `port_name`, `port_status`) VALUES ($id, '$location_global', '$location_local', '$name', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/*
* Determines if the specified location have a port
* @param string $location_global the global location
* @return boolean true if there is a spatioport exactly at the specified location ; otherwise, false.
*/
static function have_port ($location_global) {
- return (get_port_id($location_global) === null) ? false : true;
+ return (get_port_id($location_global) === NULL) ? false : true;
}
/*
* Gets the port situated exactly at the specified global location
* @param string $location_global the global location
* @return int the port ID
*/
static function get_port_id ($location_global) {
global $db;
$location_global = $db->sql_escape($location_global);
- $sql = "SELECT port_id FROM ports WHERE location_global = '$location_global'";
+ $sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global = '$location_global'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get ports", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['port_id'];
}
return null;
}
/*
* Gets default port, from specified global location
* @param string $location_global the global location
* @return Port the port near this location ; null if there isn't port there.
*/
static function from_location ($location_global) {
$havePlace = strlen($location_global) == 9;
$port_id = null;
if ($havePlace) {
//Checks if there's a port at specified location
$port_id = self::get_port_id($location_global);
}
if ($port_id == null) {
//Nearest default port.
//If place have been specified (B0001001), we've to found elsewhere
//==> B00001%
global $db;
$loc = $db->sql_escape(substr($location_global, 0, 6));
- $sql = "SELECT port_id FROM ports WHERE location_global LIKE '$loc%'";
+ $sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global LIKE '$loc%'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get port", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$port_id = $row['port_id'];
} else {
return null;
}
}
return new Port($port_id);
}
}
?>
diff --git a/includes/sessions.php b/includes/sessions.php
index ca623de..4e3bbfd 100644
--- a/includes/sessions.php
+++ b/includes/sessions.php
@@ -1,110 +1,125 @@
<?php
function decode_ip ($int_ip) {
$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
return hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
function encode_ip ($dotquad_ip) {
$ip_sep = explode('.', $dotquad_ip);
return sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}
function session_update () {
global $db, $IP, $Config;
//Nettoyage de la session
/* Initialisation */
$time_online = 5 * 60; // Temps après lequel l'utilisateur n'est plus considéré comme online
$time_session = 2 * 60 * 60; // Durée de vie de la session
$heureActuelle = time(); //Timestamp UNIX et non MySQL
/* On fait le ménage */
$sql = "UPDATE " . TABLE_SESSIONS . " SET online=0 WHERE HeureLimite < $heureActuelle";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, 'Impossible de mettre à jour les sessions (utilisateurs offline)', '', __LINE__, __FILE__, $sql);
$sql = "DELETE FROM " . TABLE_SESSIONS . " WHERE SessionLimite < $heureActuelle";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible d'effacer les sessions expirées", '', __LINE__, __FILE__, $sql);
/* Création / mise à jour de la session utilisateur */
if (!$_SESSION[ID]) {
$_SESSION[ID] = md5(genereString("AAAA1234"));
}
$sql = "SELECT * FROM " . TABLE_SESSIONS . " WHERE session_id LIKE '$_SESSION[ID]'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Problème critique avec les sessions.", '', __LINE__, __FILE__, $sql);
if ($db->sql_numrows($result) == 0) {
$sql = "INSERT INTO " . TABLE_SESSIONS . " (IP, session_id, `Where`, HeureLimite, SessionLimite) VALUES ('$IP', '$_SESSION[ID]', $Config[ResourceID], $heureActuelle + $time_online, $heureActuelle + $time_session)";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de créer une nouvelle session", '', __LINE__, __FILE__, $sql);
} else {
$sql = "UPDATE " . TABLE_SESSIONS . " SET online=1, HeureLimite = $heureActuelle + $time_online, SessionLimite= $heureActuelle + $time_session WHERE session_id = '$_SESSION[ID]'";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de mettre à jour la session", '', __LINE__, __FILE__, $sql);
}
}
function nbc () {
//Renvoi du nombre d'usagers connectés
global $db, $Config;
$sql = "SELECT count(*) FROM " . TABLE_SESSIONS . " WHERE online=1 AND `Where` = $Config[ResourceID]";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Impossible d'obtenir le nombre d'utilisateurs connectés sur le site web", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row[0];
}
function get_info ($info)
//Renvoie une variable de la session
{
global $db;
$sql = "SELECT $info FROM " . TABLE_SESSIONS . " WHERE session_id LIKE '$_SESSION[ID]'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Impossible d'obtenir $info", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row[$info];
}
function get_logged_user ()
//Renvoie toutes les informations d'un utilisateur
{
global $db;
$sql = "SELECT * FROM " . TABLE_SESSIONS . " WHERE session_id LIKE '$_SESSION[ID]'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Impossible d'obtenir les informations de l'utilisateur", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
require_once('includes/objects/user.php');
$user = new User($row['user_id']);
$user->session = $row;
return $user;
}
function set_info ($info, $value)
//Définit une variable session
{
global $db;
$value = ($value === null) ? 'NULL' : "'" . $db->sql_escape($value) . "'";
$sql = "UPDATE " . TABLE_SESSIONS . " SET $info = $value WHERE session_id LIKE '$_SESSION[ID]'";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de définir $info", '', __LINE__, __FILE__, $sql);
}
/*
* Destroys $_SESSION array values, help ID
*/
function clean_session () {
foreach ($_SESSION as $key => $value) {
if ($key != 'ID') unset($_SESSION[$key]);
}
}
+
+/*
+ * Logs in user
+ */
+
+function login ($user_id, $username) {
+ global $db;
+ $sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id LIKE '$_SESSION[ID]'";
+ if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la connexion", '', __LINE__, __FILE__, $sql);
+
+ //We send a cookie to print automatically the last username on the login
+ //page during 30 days.
+ setcookie("LastUsername", $username, time() + 2592000);
+}
+
/*
* Logs out user
*/
function logout () {
//Anonymous user in session table
global $db;
$sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '-1', perso_id = NULL WHERE session_id LIKE '$_SESSION[ID]'";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la déconnexion", '', __LINE__, __FILE__, $sql);
clean_session();
}
?>
\ No newline at end of file
diff --git a/index.php b/index.php
index 4ea7928..cd1f5c6 100644
--- a/index.php
+++ b/index.php
@@ -1,215 +1,206 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* Application entry point
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Pluton library
include('includes/core.php');
//Session
$IP = encode_ip($_SERVER["REMOTE_ADDR"]);
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION[ID] = session_id();
session_update(); //updates or creates the session
include("includes/login.php"); //login/logout
$CurrentUser = get_logged_user(); //Gets current user infos
//Gets current perso
require_once('includes/objects/perso.php');
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Skin and accent to load
define('THEME', $CurrentUser->session['Skin']);
define('ACCENT', $CurrentUser->session['Skin_accent']);
//Loads Smarty
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->template_dir = $current_dir . '/skins/' . THEME;
$smarty->compile_dir = $current_dir . '/cache/compiled';
$smarty->cache_dir = $current_dir . '/cache';
$smarty->config_dir = $current_dir;
$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
//Loads language files
initialize_lang();
lang_load('core.conf');
//Gets URL
$url = get_current_url_fragments();
-//If anonymous, prints login
+//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($CurrentUser->id < 1000) {
- //Anonymous user
- if ($url[0] == 'invite') {
- //Invitation form
- message_die(GENERAL_ERROR, "<p>Invitation system not deployed. Contact Dereckson to enable your account.</p><p>Le système d'invitation n'a pas encore été codé, contacte Dereckson pour activer ton compte.</p>", "Invitation");
- $smarty->display('invite.tpl');
- } else {
- //Login form
- if (array_key_exists('LastUsername', $_COOKIE))
- $smarty->assign('username', $_COOKIE['LastUsername']);
- if (array_key_exists('LastOpenID', $_COOKIE))
- $smarty->assign('OpenID', $_COOKIE['LastOpenID']);
- $smarty->assign('LoginError', $LoginError);
- $smarty->display('login.tpl');
- }
+ include('controllers/anonymous.php');
exit;
}
////////////////////////////////////////////////////////////////////////////////
///
/// Perso selector
///
//Handles form
if ($_POST['form'] == 'perso.create') {
$perso = new Perso();
$perso->load_from_form();
$perso->user_id = $CurrentUser->id;
//Validates forms
if (!$perso->name) $errors[] = lang_get("NoFullnameSpecified");
if (!$perso->race) {
$errors[] = lang_get("NoRaceSpecified");
$perso->race = "being";
}
if (!$perso->sex) $errors[] = lang_get("NoSexSpecified");
if (!$perso->nickname) {
$errors[] = lang_get("NoNicknameSpecified");
} else if (!Perso::is_available_nickname($perso->nickname)) {
$errors[] = lang_get("UnavailableNickname");
}
//Save or prints again forms
if (!$errors) {
+ //Saves perso, logs in
$perso->save_to_database();
$smarty->assign('NOTIFY', lang_get('NewCharacterCreated'));
$CurrentPerso = $perso;
set_info('perso_id', $perso->id);
$CurrentPerso->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
+
+ //Notifies inviter
+
} else {
$smarty->assign('WAP', join("<br />", $errors));
$smarty->assign('perso', $perso);
}
}
if ($_GET['action'] == 'perso.logout' && $CurrentPerso != null) {
//User wants to change perso
$CurrentPerso->on_logout();
$CurrentPerso = null;
} elseif ($_GET['action'] == 'perso.select') {
//User have selected a perso
$CurrentPerso = new Perso($_GET['perso_id']);
if ($CurrentPerso->user_id != $CurrentUser->id) {
//Hack
message_die(HACK_ERROR, "This isn't your perso.");
}
$CurrentPerso->on_select();
}
if (!$CurrentPerso) {
switch ($count = Perso::get_persos_count($CurrentUser->id)) {
case 0:
//User have to create a perso
$smarty->display("perso_create.tpl");
exit;
case 1:
//Autoselects only perso
$CurrentPerso = Perso::get_first_perso($CurrentUser->id);
$CurrentPerso->on_select();
break;
default:
//User have to pick a perso
$persos = Perso::get_persos($CurrentUser->id);
$smarty->assign("PERSOS", $persos);
$smarty->display("perso_select.tpl");
$_SESSION['UserWithSeveralPersos'] = true;
exit;
}
}
//Assigns current perso object as Smarty variable
$smarty->assign('CurrentPerso', $CurrentPerso);
////////////////////////////////////////////////////////////////////////////////
///
/// Tasks to execute before calling the URL controller:
/// - assert the perso is somewhere
/// - executes the smartline
///
//If the perso location is unknown, ejects it to an asteroid
if (!$CurrentPerso->location_global) {
require_once('includes/geo/place.php');
$smarty->assign('NOTIFY', lang_get('NewLocationNotify'));
$CurrentPerso->move_to(GeoPlace::get_start_location());
}
//SmartLine
include("includes/SmartLine/ZedSmartLine.php");
//Redirects user to user request controller if site.requests flag on
if (defined('PersoSelected') && array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests']) {
include('controllers/persorequest.php');
}
////////////////////////////////////////////////////////////////////////////////
///
/// Calls the specific controller to serve the requested page
///
switch ($controller = $url[0]) {
case '':
include('controllers/home.php');
break;
case 'request':
case 'page':
case 'explore':
case 'ship':
include("controllers/$controller.php");
break;
case 'who':
include('controllers/profile.php'); //Azhàr controller
break;
case 'push':
include('controllers/motd.php'); //Azhàr controller
break;
case 'quux':
//It's like a test/debug console/sandbox, you put what you want into
if (file_exists('dev/quux.php')) {
include('dev/quux.php');
} else {
message_die(GENERAL_ERROR, "Quux lost in Hollywood.", "Nay");
}
break;
default:
//TODO: returns a 404 error
dieprint_r($url, 'Unknown URL');
}
?>
\ No newline at end of file
diff --git a/lang/en/core.conf b/lang/en/core.conf
index 07c4db1..f9b5513 100644
--- a/lang/en/core.conf
+++ b/lang/en/core.conf
@@ -1,138 +1,167 @@
#Zed language config file
#Language: English
#Code: en
#Author: Dereckson
###
### Site configuration
###
SiteTitle = Zed
Product = "<strong>Zed 0.1</strong>, alpha technical preview"
###
### General stuff
###
_t = ":"
+Save = Save
###
### Login
###
Login = Login
Password = Password
OK = OK
LoginNotFound = Login not found.
IncorrectPassword = Incorrect password.
JaMata = Ja mata!
WelcomeBack = Welcome back.
OpenID = OpenID
Logout = Logout
###
### Errors
###
UnauthorizedAccess = "Unauthorized access"
SQLError = "SQL Error"
line = line
Error = Error
BackToHome = "Back to homepage"
FatalErrorScreen = Fatal error screen
FatalErrorInterrupt = Fatal error breaking screen
GeneralError = General error
PageNotFound = "Page not found"
###
### Homepage
###
Welcome = Welcome
WelcomeText = "<p>Welcome to the Zed alpha technical preview. Zed, it's a mix between a gallery, a place to meet new and existing friends, with some RPG inspiration.<br />
The concept is to have each information stored at physical places in a virtual world, like the 80s cyberspace vision. Another goal is to build a community sharing values like cooperation, freedom, ethic.</p>"
###
### Homepage - messages
###
#messages.tpl, Reply
Reply = Reply
#messages.tpl, the X link title
DeleteThisMessage = Delete this message
#home.php, messages error
MessageDeleted = Message deleted.
NotYourMessage = This message is not one of yours.
MessageAlreadyDeleted = Message already deleted.
+###
+### Account create
+###
+
+CreateAccountTitle = Create an account
+CreateAccountIntro = "<p>Welcome to Zed.<br />To get an account, you need an invite code. To get an invite code, ask who tell you about Zed.</p>"
+
+YourLogin = The login you want
+InviteCode = Your invite code
+YourEmail = Your e-mail
+
+EnterInviteCodePromptMessage = "Your invite code is something like ABC123."
+EnterUsernamePromptMessage = "Enter your username, in lowercase (11 characters max.).<br />It's your usual username, not your character name."
+EnterEmailPromptMessage = "Enter your e-mail. It will used (1) as password recovery method (2) to send you notification of new messages or events you've configured.<br />We don't like spam, so we take all the measures to protect your mail."
+
+IncorrectInviteCode = "Your invite code's format isn't valid. It's something like ABC123."
+InviteCodeAlreadyClaimed = "This invite code were valid. But it have already been claimed."
+
+CreateAccountImageTitle = "Zed is for human being. But it's also for people defining themselves like other beings than humans."
+CreateAccountImageAlt = "A strange-looking white picture. An half circle from top right to bottom right, then the brush come back in spirale to create a big white spot. Some brushes effects add fringes at start and end. Grayscale spots have been added in main circle."
+
+MissingUsername = "You need to provide a login."
+LoginUnavailable = "This login is already taken."
+MissingPassword = "You need to provide a password."
+InviteHaveBeenClaimed = "Your invite %s have just been claimed."
+AccountCreated = "Your account is created. Welcome to Zed."
+
###
### Perso create/select
###
NewCharacterCreated = New character created
CreateCharacter = Create a character
EditCharacter = Edit %s information
NoSexSpecified = "Pick a sex, or '<em>Neutral</em>' if you don't want to tell it."
NoNicknameSpecified = "You must pick a nickname, it's like your login to identify your character."
NoFullnameSpecified = "All beings must have a name."
NoRaceSpecified = "You've to specify a race: '<em>humanoid</em>' for human and co.<br />If you don't want to specify a race, use the generic '<em>being</em>'."
NicknameUnavailable = "This nickname is already used.<br />Choose a more original one."
PickPerso = Pick your perso
SwapPerso = "Swap perso (%s's logout)"
NewLocationNotify = "You're slowly awaking in a place you don't recognize."
###
### Places
###
CurrentLocation = "Current location"
UnknownBody = "Unknown asteroid"
UnknownPlace = "Unknown place"
WherePlace = "%s @ %s"
SpaceAround = "Space around %s"
hypership = hypership
asteroid = asteroid
moon = moon
planet = planet
star = star
orbital = orbital
place = place
ship = ship
###
### Stories
###
InvalidStoryGUID = "In story mode, you can't use previous/back URL."
ExpiredStorySession = "Story choices URL are temporary.<br />You can't bookmark them or use in another session."
###
### Requests
###
+Request = Request
Title = Title
###
### MOTD
###
PushMessage = Push a message to the header
TextToAdd = Text to add
TextToAddWarning = Warning: once published, it can't be (easily) removed.
Rendering = How it will be printed?
RenderingWhere = "At the top right header corner:"
DummyPlaceholder = Here your message.
Push = Push
Published = Published :)
\ No newline at end of file
diff --git a/lang/fr/core.conf b/lang/fr/core.conf
index 8412203..ed6deb9 100644
--- a/lang/fr/core.conf
+++ b/lang/fr/core.conf
@@ -1,139 +1,157 @@
#Zed language config file
#Language: English
#Code: fr
#Author: Dereckson
###
### Site configuration
###
SiteTitle = Zed
Product = "<strong>Zed 0.1</strong>, alpha technical preview"
###
### General stuff
###
_t = " :"
+Save = Enregistrer
###
### Login
###
Login = Login
Password = Password
OK = OK
LoginNotFound = Login introuvable.
IncorrectPassword = Mot de passe incorrect.
JaMata = Ja mata!
WelcomeBack = Welcome back.
OpenID = OpenID
Logout = Déconnexion
###
### Homepage
###
Welcome = Bienvenue
WelcomeText = "<p>Bienvenue sur la version alpha de Zed, un hybride un peu étrange entre une galerie, un endroit où rencontrer ses amis ou s'en faire de nouveaux, avec une légère inspiration RPG, dans un environnement galactique inspiré des romans de la Culture de Iain M. Banks.</p>
<p>Le concept est d'expérimenter ce qui se passe lorsque chaque information est dans un espace précis, un peu comme la vision cyberpunk des années 80 du cyberespace. Un autre but est de créer une communauté partagant des valeurs de respect, de coopération, de liberté et d'éthique.</p>"
###
### Homepage - Messages
###
#messages.tpl, Reply
Reply = Répondre
#messages.tpl, the X link title
DeleteThisMessage = Effacer ce message
#home.php, messages error
MessageDeleted = Message effacé.
NotYourMessage = Hey, ce message appartient à autrui !
MessageAlreadyDeleted = Message déjà effacé
###
### Errors
###
UnauthorizedAccess = "Accès non autorisé"
SQLError = "Erreur dans la requête SQL"
line = ligne
Error = Erreur
BackToHome = "Retour à la page d'accueil"
FatalErrorScreen = Fatal error screen
FatalErrorInterrupt = Fatal error screen (interruption)
GeneralError = "Erreur"
PageNotFound = "Cette page n'existe pas."
+###
+### Account create
+###
+
+CreateAccountTitle = Créer un compte
+CreateAccountIntro = "<p>Bienvenue sur Zed.<br />Zed est un site privé uniquement accessible suite à l'invitation d'un membre.</p>"
+
+YourLogin = Le login de votre choix
+InviteCode = "Votre code d'invitation"
+YourEmail = Votre adresse e-mail
+
+EnterInviteCodePromptMessage = "Votre code d'invitation ressemble à ABC123."
+EnterUsernamePromptMessage = "Votre login sera en minuscule et d'au plus onze caractères.<br />Il sera uniquement utilisé pour vous identifier, votre login NE sera PAS le nom de votre perso."
+EnterEmailPromptMessage = "Votre adresse sera utilisée pour vous permettre de modifier votre mot de passe en cas d'oubli. Vous pourrez également configurer des notifications en cas de nouveau message & co, mais par défaut c'est désactivé."
+
+IncorrectInviteCode = "Format invalide du code d'invitation,<br />recherchez quelque chose ressemblant à ABC123."
+
###
### Perso create/select
###
NewCharacterCreated = Nouveau perso créé.
CreateCharacter = Nouveau perso
EditCharacter = Éditer les infos de %s
NoSexSpecified = "Pick a sex, or '<em>Neutral</em>' if you don't want to tell it."
NoNicknameSpecified = "You must pick a nickname, it's like your login to identify your character."
NoFullnameSpecified = "All beings must have a name."
NoRaceSpecified = "You've to specify a race: '<em>humanoid</em>' for human and co.<br />If you don't want to specify a race, use the generic '<em>being</em>'."
NicknameUnavailable = "This nickname is already used.<br />Choose a more original one."
PickPerso = "Sélectionnez votre perso"
SwapPerso = "Changer de perso (déco %s)"
NewLocationNotify = "Vous vous réveillez lentement dans un endroit inconnu"
###
### Places
###
CurrentLocation = "Localisateur"
UnknownBody = "Astéroïde inconnu"
UnknownPlace = "Endroit inconnu"
WherePlace = "%2$s, %1$s."
SpaceAround = "%s et l'espace autour"
hypership = hypership
asteroid = astéroïde
moon = lune
planet = planète
star = étoile
orbital = orbitale
place = endroit
ship = vaisseau
###
### Stories
###
InvalidStoryGUID = "En mode récit, il n'est pas possible <br />d'utiliser les boutons précédents et suivants."
ExpiredStorySession = "Les URL de choix sont temporaires.<br />Il n'est pas possible de les bookmark pour y revenir."
###
### Requests
###
-
+Request = Requête
Title = Titre
###
### MOTD
###
PushMessage = Publier un message tout en haut
TextToAdd = Texte à ajouter
TextToAddWarning = "Une fois publié, ne peut être facilement enlevé."
Rendering = Aperçu
RenderingWhere = "Coin supérieur droit de la page :"
DummyPlaceholder = Lorem ipsum dolor.
Push = Publier
Published = Publié :)
\ No newline at end of file
diff --git a/skins/zed/perso_footer.tpl b/skins/zed/perso_footer.tpl
index 7922abe..f41683f 100644
--- a/skins/zed/perso_footer.tpl
+++ b/skins/zed/perso_footer.tpl
@@ -1,11 +1,13 @@
<div class="clear"></div>
<hr />
- <div class="grid_12 alpha">
- <p>[ {#Product#} ]</p>
+ <div id="footer">
+ <div class="grid_12 alpha">
+ <p>[ {#Product#} ]</p>
+ </div>
+ <div class="grid_4 omega">
+ <p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
+ </div>
</div>
- <div class="grid_4 omega">
- <p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
- </div
</div>
</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/skins/zed/perso_header.tpl b/skins/zed/perso_header.tpl
index f8e387b..3e2f1cf 100644
--- a/skins/zed/perso_header.tpl
+++ b/skins/zed/perso_header.tpl
@@ -1,53 +1,56 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#SiteTitle#}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
<!-- Calls dojo -->
<script src="/{#StaticContentURL#}js/dojo/dojo/dojo.js" type="text/javascript"
djConfig="isDebug: false, parseOnLoad: true"></script>
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/forms.css" />
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.Button");
+ dojo.require("dojox.validate.regexp");
+ dojo.require("dojox.form.PasswordValidator");
+
dojo.require("dojo.parser");
</script>
</head>
<body class="tundra">
<!-- Header -->
<div id="header">
<div id="header_content">
<div class="container_16">
<div class="grid_4 alpha omega suffix_8">
<a href="{get_url()}"><img src="{#StaticContentURL#}/img/zed/logo.png" src="Zed logo" border=0 /></a>
</div>
<div class="clear"></div>
</div>
</div>
</div>
<div class="clear"></div>
<!-- Content -->
<div class="container_16">
{if $WAP}
<!-- WAP -->
<div class="grid_16 alpha omega">
<div class="wap">{$WAP}</div>
</div>
{/if}
{if $NOTIFY}
<!-- Notify -->
<div class="grid_16 alpha omega">
<div class="notify">{$NOTIFY}</div>
</div>
{/if}
diff --git a/skins/zed/requests/aid.reach.tpl b/skins/zed/requests/aid.reach.tpl
index 3693cf4..e9fa3ae 100644
--- a/skins/zed/requests/aid.reach.tpl
+++ b/skins/zed/requests/aid.reach.tpl
@@ -1,20 +1,20 @@
<!-- DIJIT -->
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
</script>
<!-- Request form: aid.reach -->
<h1>Communicator</h1>
<h2>Send a request to the hypership</h2>
<form dojoType="dijit.form.Form" name="aid.reach" method="post">
<div class="row">
<label class="firstLabel" for="PostTitle">{#Title#}</label>
<input dojoType="dijit.form.ValidationTextBox" value="{$request->title}" type="text" id="PostTitle" name="title" class="long" required="true" />
</div>
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />Send</button>
</div>
- <p>Your request will be sent to humans.</p>
+ <p><strong>Warning:</strong> Your request will be sent to and handled by humans.</p>
</form>
\ No newline at end of file
diff --git a/skins/zed/tutorial/hypership_reach.tpl b/skins/zed/tutorial/hypership_reach.tpl
index a730a19..d9f713d 100644
--- a/skins/zed/tutorial/hypership_reach.tpl
+++ b/skins/zed/tutorial/hypership_reach.tpl
@@ -1,31 +1,32 @@
{if $DOJO}
{/if}
<!-- Floating panes -->
<script type="text/javascript" src="{#StaticContentURL#}/js/dojo/dojox/layout/FloatingPane.js"></script>
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/js/dojo/dojox/layout/resources/FloatingPane.css" />
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/js/dojo/dojox/layout/resources/ResizeHandle.css" />
<!-- Dock -->
<style type="text/css">
@import "{#StaticContentURL#}/js/dojo/dijit/themes/dijit.css";
</style>
+
<!-- Help to reach the hypership -->
<div dojoType="dojox.layout.FloatingPane" title="Join the hypership" resizable="true" id="floaterHypershipReach" class="floatingPaneTutorial" duration="300">
{if $CurrentPerso->location_global[0] == "S"}
<p>Congratulations! You found a ship.</p>
<p>You're aboard the {$CurrentPerso->location->ship->name}.</p>
{if $controller == "ship"}
<p>In the future, you will able to explore the ship, but this is not yet implemented yet in this alpha preview.</p>
{if $note == ""}
<p>Your notes is the only information generally available about ships. For reference, you should note something like "Took the {$CurrentPerso->location->ship->name} at {get_hypership_time()} from ... to the hypership."</p>
{/if}
{/if}
{else}
<p>{sprintf(#WhereYouAre#, $CurrentPerso->where(), lang_get($CurrentPerso->location->body_kind))}</p>
<p>{#WhereTheHypershipIs#}</p>
<p>{#HowToJoinIt#}</p>
{/if}
- </div>
\ No newline at end of file
+ </div>

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 8, 15:23 (3 w, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
21103
Default Alt Text
(86 KB)

Event Timeline