Page MenuHomeCode

No OneTemporary

diff --git a/content/scenes/B00001001.tpl b/content/scenes/B00001001.tpl
index e2f8a1c..0ea5fb7 100644
--- a/content/scenes/B00001001.tpl
+++ b/content/scenes/B00001001.tpl
@@ -1,173 +1,177 @@
+ <!--
+ Global location: B00001001
+ -->
+
<!-- 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;
}
#uploadDialog label {
color: black;
}
</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>-->
<!-- Navigation -->
{$loc = explode('C', $CurrentPerso->location_local)}{$loc[0] = substr($loc[0], 1)}
<div class="grid_7 alpha">
{#Sector#} T<span id="TowerFloor">{$loc[0]}</span>
</div>
<div class="grid_2" style="text-align: center">
{#Couloir#} <span id="TowerCouloir">{$loc[1]}</span>
</div>
<div class="grid_7 omega" style="text-align: right">
<a href="{if $loc[0] == 1}#{else}/do.php/set_local_location/T{$loc[0] - 1}C{$loc[1]}?redirectTo={get_url()}{/if}" onClick="passage.goUp(); return false;">{#GoUp#}</a> | <a href="/do.php/set_local_location/T{$loc[0] + 1}C{$loc[1]}?redirectTo={get_url()}" onClick="passage.goDown(); return false;">{#GoDown#}</a>
</div>
<!-- Passage -->
<div class="grid_16 alpha omega">
<div id="passage">
<div id="passage_gallery"></div>
<!-- Navigation -->
</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})}?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: 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(1);
//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/content/scenes/B00001002.tpl b/content/scenes/B00001002.tpl
index b8ea316..3033f4d 100644
--- a/content/scenes/B00001002.tpl
+++ b/content/scenes/B00001002.tpl
@@ -1,33 +1,49 @@
+ <!--
+ Global location: B00001002
+ -->
+
<div class="grid_7 alpha">
{$xyz = explode(',', substr($CurrentPerso->location_local, 1, -1))}
{$x = $xyz[0]}{$y = $xyz[1]}{$z = $xyz[2]}
Sector C<span id="sector">{GeoOctocube::get_sector($x, $y, $z)}</span>
</div>
<div class="grid_2" style="text-align: center;">
Zone <span id="area">{abs($x)}-{abs($y)}</span>
</div>
<div class="grid_7 omega" style="text-align: right; margin-bottom: 1em;">
Niveau <span id="level">{abs($z)}</span>
</div>
<div class="clear"></div>
<div class="content_wrapper">
- <h1>HyperShip core builder</h1>
- <div class="content">
+ <h1>HyperShip builder</h1>
+ <div class="grid_9 suffix_1 content alpha">
<h2>This area is buildable.</h2>
<p>You can take over this part of the ship, transform it and design it as you want.</p>
<p>To start, you can:</p>
<ul>
<li>Create a 960px wide picture with your scene background.</li>
<li>Define which parts of your picture are exits to another zone or level.</li>
</ul>
<p>If you want, you will also able to:</p>
<ul>
<li>Add descriptions to part of the area (like in the 90s adventure games)</li>
<li>Create a textual scenario (like in 80s choose your own adventure books)</li>
<li>Enhance the area with javascript or HTML5 (like in 2010)</li>
</ul>
</div>
+ <div class="grid_6 omega">
+ <p><a href="{get_url('builder')}">Start to build</a></p>
+
+ <p><a href="{get_url('do.php')}/local_move/0,1,0?redirectTo=/">Go north</a><br />
+ <a href="{get_url('do.php')}/local_move/1,0,0?redirectTo=/">Go east</a><br />
+ <a href="{get_url('do.php')}/local_move/0,-1,0?redirectTo=/">Go south</a><br />
+ <a href="{get_url('do.php')}/local_move/-1,0,0?redirectTo=/">Go west</a></p>
+
+ <p><a href="{get_url('do.php')}/local_move/0,0,1?redirectTo=/">Climb up</a><br />
+ <a href="{get_url('do.php')}/local_move/0,0,-1?redirectTo=/">Climb down</a></p>
+ </div>
+ <div class="clear fixclear"></div>
</div>
diff --git a/content/scenes/B00002.tpl b/content/scenes/B00002.tpl
index d702d27..d046fbf 100644
--- a/content/scenes/B00002.tpl
+++ b/content/scenes/B00002.tpl
@@ -1,6 +1,7 @@
-{$code = substr($CurrentPerso->location_global, 0, 6)}
- <!-- {$code} -->
- <img class="SpaceScene" src="{$SCENE_URL}/{$code}.png" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
+ <!--
+ Global location: B00002
+ -->
+ <img class="SpaceScene" src="{$SCENE_URL}/B00002.png" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
<map name="SceneMap" id="SceneMap">
<area shape="circle" coords="155,144,93" href="{get_url('explore')}" alt="{$CurrentPerso->location->body->name}" />
</map>
\ No newline at end of file
diff --git a/content/scenes/B00003.tpl b/content/scenes/B00003.tpl
index 91c6a34..51211f7 100644
--- a/content/scenes/B00003.tpl
+++ b/content/scenes/B00003.tpl
@@ -1,6 +1,7 @@
-{$code = substr($CurrentPerso->location_global, 0, 6)}
- <!-- {$code} -->
- <img class="SpaceScene" src="{$SCENE_URL}/{$code}.jpg" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
+ <!--
+ Global location: B00003
+ -->
+ <img class="SpaceScene" src="{$SCENE_URL}/B00003.jpg" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
<map name="SceneMap" id="SceneMap">
<area shape="circle" coords="732,207,129" href="{get_url('explore')}" alt="{$CurrentPerso->location->body->name}" />
</map>
\ No newline at end of file
diff --git a/controllers/footer.php b/controllers/footer.php
index f611763..c0fb099 100644
--- a/controllers/footer.php
+++ b/controllers/footer.php
@@ -1,54 +1,54 @@
<?php
/**
* Footer
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a redirect controller to call the relevant controller,
* according to the location.
*
* It handles and prints the footer elements (tutorial, SmartLine, html footer)
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
if (!defined('NO_FOOTER_EXTRA')) {
///
/// Tutorials div
///
- if ($CurrentPerso->flags['hypership.reached'] < 1 && $controller != 'explore') {
+ if ($controller != 'explore' && (!array_key_exists('hypership.reached', $CurrentPerso->flags) || $CurrentPerso->flags['hypership.reached'] < 1)) {
if (!DOJO) $smarty->display('tutorial/dojo.tpl');
lang_load("tutorials.conf", "ReachHypership");
$smarty->assign('controller', $controller);
$smarty->display('tutorial/hypership_reach.tpl');
}
///
/// Footer options
///
$smarty->assign('MultiPerso', isset($_SESSION['UserWithSeveralPersos']) && $_SESSION['UserWithSeveralPersos']);
$smarty->assign('SmartLinePrint', (string)$CurrentPerso->get_flag('site.smartline.show') != "0");
$smarty->assign('SmartLineFormMethod', $CurrentPerso->get_flag('site.smartline.method'));
}
///
/// HTML output
///
lang_load('footer.conf');
$smarty->display('footer.tpl');
-?>
\ No newline at end of file
+?>
diff --git a/dev/quux.php b/dev/quux.php
index ac1539a..adffba0 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,112 +1,130 @@
<?php
require_once('includes/objects/ship.php');
require_once('includes/objects/port.php');
require_once('includes/objects/application.php');
require_once('includes/objects/content.php');
require_once('includes/objects/message.php');
require_once('includes/objects/invite.php');
require_once('includes/cache/cache.php');
- require_once('includes/cache/cache.php');
include('controllers/header.php');
- $case = 'travel';
+ $case = 'index_scenes';
switch ($case) {
+ case 'index_scenes':
+ $time[] = microtime();
+ require_once('includes/geo/scene.php');
+ require_once('includes/geo/sceneindex.php');
+ $cache = Cache::load();
+ if ($index = $cache->get('GeoSceneIndex')) {
+ $index = unserialize($index);
+ } else {
+ $index = GeoSceneIndex::Load(SCENE_DIR);
+ $cache->set('GeoSceneIndex', serialize($index));
+ }
+ $time[] = microtime();
+ echo '<H2>GeoSceneIndex</H2>';
+ dprint_r($index);
+ echo '<H2>Time (ms)</H2>';
+ dprint_r(1000 * ($time[1] - $time[0]));
+ dieprint_r($time);
+ break;
+
case 'travel':
require_once('includes/travel/travel.php');
$travel = Travel::load();
dieprint_r($travel);
break;
case 'spherical':
require_once('includes/geo/galaxy.php');
echo '<H2>Spherical coordinates test</H2>';
echo '<table cellpadding=8>';
echo "<tr><th>Name</th><th>Type</th><th>Cartesian coords</th><th>Spherical I</th><th>Spherical II</th><th>Pencil coordinates</th></tr>";
$objects = GeoGalaxy::get_coordinates();
foreach ($objects as $row) {
echo "<tr><th style='text-align: left'>$row[0]</th><td>$row[1]</td><td>$row[2]</td>";
$pt = $row[2];
echo '<td>(', implode(', ', $pt->to_spherical()), ')</td>';
echo '<td>(', implode(', ', $pt->to_spherical2()), ')</td>';
$pt->translate(500, 300, 200, 2);
echo '<td>', $pt, '</td>';
echo '</tr>';
}
echo '</table>';
break;
case 'travel':
require_once('includes/travel/travel.php');
require_once('includes/travel/place.php');
$cache = Cache::load();
$travel = $cache->get('zed_travel');
if ($travel == '') {
$travel_nocached = new Travel();
$travel_nocached->load_xml("content/travel.xml");
$cache->set('zed_travel', serialize($travel_nocached));
} else {
$travel = unserialize($travel);
}
dieprint_r($travel);
break;
case 'perso.create.notify':
$testperso = Perso::get(4733);
$message = new Message();
$message->from = 0;
$message->to = invite::who_invited(4733);
$url = get_server_url() . get_url('who', $testperso->nickname);
$message->text = sprintf(lang_get('InvitePersoCreated'), $testperso->name, $url);
$message->send();
dieprint_r($message);
break;
case 'pushdata';
echo '
<h2>/api.php/app/pushdata</h2>
<form method="post" action="/api.php/app/pushdata?mode=file&key=37d839ba-f9fc-42ca-a3e8-28053e979b90" enctype="multipart/form-data">
<input type="file" name="datafile" /><br />
<input type="submit" value="Send file" />
</form>
';
break;
case 'thumbnail':
$content = new Content(1);
dprint_r($content);
$content->generate_thumbnail();
break;
case 'port':
echo '<h2>Port::from_location test</h2>';
$locations = array("B00002", "B00002123", "B00001001", "xyz: [800, 42, 220]");
foreach ($locations as $location) {
dprint_r(Port::from_location($location));
}
break;
case 'ext':
$file = 'dev/foo.tar';
echo "<h2>$file</h2>";
echo "<h3>.tar.bz2</h3>";
echo ereg('\.tar\.bz2$', $file);
echo "<h3>.tar</h3>";
echo ereg('\.tar$', $file);
break;
case 'app':
echo Application::from_api_key("37d839ba-f9fc-42ca-a3e8-28053e979b90")->generate_userkey();
break;
case '':
dieprint_r("No case currently selected.");
break;
}
include('controllers/footer.php');
?>
\ No newline at end of file
diff --git a/do.php b/do.php
index 0cd051b..598e08b 100644
--- a/do.php
+++ b/do.php
@@ -1,289 +1,362 @@
<?php
/**
* AJAX callbacks
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* As main controller could potentially be interrupted (e.g. if site.requests
* flag is at 1, user is redirected to controllers/userrequest.php), all AJAX
* queries should be handled by this script and not directly by the controllers.
*
* Standard return values:
* -7 user is logged but perso isn't selected,
* -9 user is not logged.
*
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Constants
///
//We define one negative number constant by standard erroneous return value.
/**
* Magic number which indicates the user is not logged in.
*/
define('USER_NOT_LOGGED', -9);
/**
* Magic number which indicates the user is logged in, but haven't selected its perso.
*/
define('PERSO_NOT_SELECTED', -7);
////////////////////////////////////////////////////////////////////////////////
///
/// 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);
}
//Requires user and perso
if ($CurrentUser->id < 1000) {
echo USER_NOT_LOGGED;
exit;
}
if (!$CurrentPerso) {
echo PERSO_NOT_SELECTED;
exit;
}
//Loads Smarty (as it handles l10n, it will be used by lang_get)
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->template_dir = $current_dir . '/skins/zed';
$smarty->compile_dir = $current_dir . '/cache/compiled';
$smarty->cache_dir = $current_dir . '/cache';
$smarty->config_dir = $current_dir;
//Loads language files
initialize_lang();
lang_load('core.conf');
////////////////////////////////////////////////////////////////////////////////
///
/// Actions definitions
///
/**
* Actions class
*
* Each method is called by first part of your URL, other parts are arguments
* e.g. /do.php/validate_quux_request/52 = Actions::validate_quux_request(52);
*
* You can also use $_GET, $_POST or better $_REQUEST.
*
* Don't echo the value but return it, so we can in the future implement custom
* formats like api_output();
*/
class Actions {
/**
* Checks the arguments hash and determines wheter it is valid.
*
* @param Array $args the arguments, the last being the hash
* @return boolean true if the hash is valid ; otherwise, false.
*/
static private function is_hash_valid ($args) {
global $Config;
return array_pop($args) == md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/**
* Handles a allow/deny perso request.
*
* @param string $request_flag the request flag to clear
* @param string $store 'perso' or 'registry'
* @param string $key the perso flag or registry key
* @param string $value the value to store
* @param string $hash the security hash
* @return boolean true if the request is valid and have been processed ; otherwise, false.
*/
static function perso_request ($request_flag, $store, $key, $value, $hash) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 4) return false;
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Sets flag
switch ($store) {
case 'perso':
$CurrentPerso->set_flag($key, $value);
break;
case 'registry':
registry_set($key, $value);
break;
default:
//Unknown storage location
return false;
}
//Clears request flag
if ((string)$request_flag !== "0") {
$CurrentPerso->delete_flag($request_flag);
}
return true;
}
/**
* Sets current perso's local location.
*
* We don't require a security hash. If the users want to play with it, no problem.
- * You generally moves inside a global location as you wish.
+ * You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $location_local the local location
* @return GeoLocation the current perso's GeoLocation object
*/
static function set_local_location ($location_local) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) return null;
//Moves current perso to specified location
$CurrentPerso->move_to(null, $location_local);
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
+ /**
+ * Moves the current perso's, setting a new local location.
+ *
+ * We don't require a security hash. If the users want to play with it, no problem.
+ * You generally move inside a global location as you wish.
+ * So, if you write a story capturing a perso, use flags to handle this escape!
+ *
+ * @param string $move the move (coordinates or direction)
+ * @param int $factor a number multipling the specified move [optional]
+ * @return GeoLocation the current perso's GeoLocation object
+ *
+ * e.g. to move from 2 units to east, you can use one of those instructions:
+ * local_move('east', 2);
+ * local_move('2,0,0');
+ * local_move('1,0,0', 2);
+ *
+ * Valid moves string are north, east, south, west, up and down.
+ * Valid moves coordinates are x,y,z (3 integers, comma as separator)
+ */
+ static function local_move ($move, $factor = 1) {
+ global $CurrentPerso;
+
+ //Ensures we've the correct amount of arguments
+ if (func_num_args() < 1) return null;
+
+ //Parses $move
+ switch ($move) {
+ case 'north':
+ $move = array(0, 1, 0);
+ break;
+
+ case 'east':
+ $move = array(1, 0, 0);
+ break;
+
+ case 'south':
+ $move = array(0, -1, 0);
+ break;
+
+ case 'west':
+ $move = array(-1, 0, 0);
+ break;
+
+ case 'up':
+ $move = array(0, 0, 1);
+ break;
+
+ case 'down':
+ $move = array(0, 0, -1);
+ break;
+
+ default:
+ $move = split(',', $move, 3);
+ foreach ($move as $coordinate) {
+ if (!is_numeric($coordinate)) {
+ return null;
+ }
+ }
+ }
+
+ //Moves current perso to specified location
+ if ($location_local = GeoPoint3D::fromString($CurrentPerso->location->local)) {
+ $location_local->translate($move[0] * $factor, $move[1] * $factor, $move[2] * $factor);
+ $CurrentPerso->move_to(null, $location_local->sprintf("(%d, %d, %d)"));
+
+ //Returns GeoLocation relevant instance
+ return $CurrentPerso->location;
+ }
+
+ //Old local location weren't a GeoPoint3D
+ return null;
+ }
+
/**
* Handles upload content form.
*
* @return string new content path
*/
static function upload_content () {
global $CurrentPerso, $CurrentUser;
require_once('includes/objects/content.php');
//Initializes a new content instance
$content = new Content();
$content->load_from_form();
$content->user_id = $CurrentUser->id;
$content->perso_id = $CurrentPerso->id;
$content->location_global = $CurrentPerso->location_global;
//Saves file
if ($content->handle_uploaded_file($_FILES['artwork'])) {
$content->save_to_database();
$content->generate_thumbnail();
return true;
}
return false;
}
/**
* Gets multimedia content for the specified location
*
* @param string $location_global The global location (local is to specified in ?location_local parameter)
* @return Array an array of Content instances
*/
static function get_content ($location_global) {
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) return null;
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Checks local location is specified somewhere (usually in $_GET)
if (!array_key_exists('location_local', $_REQUEST)) {
return false;
}
//Gets content
require_once('includes/objects/content.php');
return Content::get_local_content($location_global, $_REQUEST['location_local']);
}
}
////////////////////////////////////////////////////////////////////////////////
///
/// Handles request
///
//You really should use $_SERVER['PATH_INFO']
//i.e. calling /do.php/your request without any mod rewrite intervention
//
//If you choose otherwise, uncomment and tweak one of the following lines:
//$Config['SiteURL'] = 'http://yourserver/zed/do.php';
//$Config['SiteURL'] = get_server_url() . '/do.php';
$args = get_current_url_fragments();
$method = array_shift($args);
if ($_REQUEST['debug']) {
//Debug version
//Most of E_STRICT errors are evaluated at the compile time thus such errors
//are not reported
ini_set('display_errors', 'stderr');
error_reporting(-1);
if (method_exists('Actions', $method)) {
$result = call_user_func_array(array('Actions', $method), $args);
echo json_encode($result);
} else {
echo "<p>Method doesn't exist: $method</p>";
}
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
echo "<p>Instead to print a callback value, redirects to <a href=\"$_REQUEST[redirectTo]\">$_REQUEST[redirectTo]</a></p>";
}
} else {
//Prod version doesn't prints warning <== silence operator
if (method_exists('Actions', $method)) {
$result = @call_user_func_array(array('Actions', $method), $args);
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
header("location: " . $_REQUEST['redirectTo']);
} else {
echo json_encode($result);
}
}
}
?>
\ No newline at end of file
diff --git a/includes/autoload.php b/includes/autoload.php
index 35a2302..a6d3700 100644
--- a/includes/autoload.php
+++ b/includes/autoload.php
@@ -1,77 +1,81 @@
<?php
/**
* Autoloader
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This file provides an __autoload function to help loading objects files.
*
* This function is autogenerated by the TCL script dev/scripts/autoload.tcl
*
* @package Zed
* @subpackage Keruald
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* This magic method is called when a class can't be loaded
*
* @param string $className the class to load
*/
function __autoload ($className) {
//Classes
$classes['Cache'] = 'includes/cache/cache.php';
$classes['CacheMemcached'] = 'includes/cache/memcached.php';
$classes['CacheVoid'] = 'includes/cache/void.php';
+
+ $classes['Content'] = 'includes/objects/content.php';
+ $classes['ContentFile'] = 'includes/content/file.php';
+ $classes['ContentLocation'] = 'includes/content/location.php';
+ $classes['ContentZone'] = 'includes/content/zone.php';
$classes['GeoBody'] = 'includes/geo/body.php';
$classes['GeoGalaxy'] = 'includes/geo/galaxy.php';
$classes['GeoLocation'] = 'includes/geo/location.php';
$classes['GeoPlace'] = 'includes/geo/place.php';
$classes['GeoPoint3D'] = 'includes/geo/point3D.php';
$classes['GeoScene'] = 'includes/geo/scene.php';
$classes['Application'] = 'includes/objects/application.php';
- $classes['Content'] = 'includes/objects/content.php';
$classes['Invite'] = 'includes/objects/invite.php';
$classes['Message'] = 'includes/objects/message.php';
$classes['MOTD'] = 'includes/objects/motd.php';
$classes['Perso'] = 'includes/objects/perso.php';
$classes['Port'] = 'includes/objects/port.php';
$classes['Profile'] = 'includes/objects/profile.php';
$classes['ProfileComment'] = 'includes/objects/profilecomment.php';
$classes['ProfilePhoto'] = 'includes/objects/profilephoto.php';
$classes['Ship'] = 'includes/objects/ship.php';
$classes['User'] = 'includes/objects/user.php';
$classes['SettingsPage'] = 'includes/settings/page.php';
$classes['Setting'] = 'includes/settings/setting.php';
$classes['Settings'] = 'includes/settings/settings.php';
$classes['StoryChoice'] = 'includes/story/choice.php';
$classes['StoryHook'] = 'includes/story/hook.php';
$classes['DemoStoryHook'] = 'includes/story/hook_demo.php';
$classes['SpatioportStoryHook'] = 'includes/story/hook_spatioport.php';
$classes['StorySection'] = 'includes/story/section.php';
$classes['Story'] = 'includes/story/story.php';
$classes['TravelPlace'] = 'includes/travel/place.php';
$classes['Travel'] = 'includes/travel/travel.php';
//Loader
if (array_key_exists($className, $classes)) {
require_once($classes[$className]);
}
}
-?>
\ No newline at end of file
+?>
diff --git a/includes/config.php b/includes/config.php
index b20b21f..c5e0507 100644
--- a/includes/config.php
+++ b/includes/config.php
@@ -1,246 +1,250 @@
<?php
/**
* Autogenerable configuration file
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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_CONTENT_FILES', $prefix . 'content_files');
+define('TABLE_CONTENT_LOCATIONS', $prefix . 'content_locations');
+define('TABLE_CONTENT_ZONES', $prefix . 'content_zones');
+define('TABLE_CONTENT_ZONES_LOCATIONS', $prefix . 'content_zones_locations');
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_PROFILES_TAGS', $prefix . 'profiles_tags');
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'] = 'Lorem ipsum dolor';
//When reading files, buffer size
define('BUFFER_SIZE', 4096);
////////////////////////////////////////////////////////////////////////////////
/// ///
/// III. Script URLs ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Apache httpd, 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';
*
* Apache httpd, 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]
*
* nginx:
*
* Use same config.php settings than Apache httpd, with mod_rewrite.
*
* In your server block:
* location / {
* #Serves static files if they exists, with one month cache
* if (-f $request_filename) {
* expires 30d;
* break;
* }
*
* #Sends all non existing file or directory requests to index.php
* if (!-e request_filename) {
* rewrite ^(.+)$ /index.php last;
* #Or if you use a subdirectory:
* #rewrite ^(.+)$ /hypership/index.php last;
* }
* }
*
* location ~ \.php$ {
* #Your instructions to pass query to your FastCGI process, like:
* fastcgi_pass 127.0.0.1:9000;
* fastcgi_param SCRIPT_FILENAME /var/www/zed$fastcgi_script_name;
* include fastcgi_params;
* }
*
*
* 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.
//
//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. Caching ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Some data (Smarty, OpenID and sessions) are cached in the cache directory.
*
* Security tip: you can move this cache directory outside the webserver tree.
*/
define('CACHE_DIR', 'cache');
/*
* Furthermore, you can also enable a cache engine, like memcached, to store
* data from heavy database queries, or frequently accessed stuff.
*
* To use memcached:
* - $Config['cache']['engine'] = 'memcached';
* - $Config['cache']['server'] = 'localhost';
* - $Config['cache']['port'] = 11211;
*
* To disable cache:
* - $Config['cache']['engine'] = 'void';
* (or don't write nothing at all)
*/
$Config['cache']['engine'] = 'void';
////////////////////////////////////////////////////////////////////////////////
/// ///
/// VI. 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_DIR . '/sessions');
ini_set('session.gc_maxlifetime', 345600); //4 days, for week-end story pause and continue url
?>
diff --git a/includes/geo/location.php b/includes/geo/location.php
index 66a2d55..31d0704 100644
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,432 +1,436 @@
<?php
/**
* Geo location class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 18:52 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('body.php');
require_once('place.php');
require_once('point3D.php');
require_once('includes/objects/ship.php');
/**
* Geo location class
*
* This class contains properties to get, set or compare a location and
* explore the geo classes linked to.
*
* It quickly allow to parse through the location classes in templates and
* controllers.
*
* @todo initializes $point3D from $body or $ship own locations;
* @todo improve GeoLocation documentation (especially magic properties)
*/
class GeoLocation {
/**
* An array of strings containing location data.
*
* In the current class implementation,
* the first element is the global location
* and the second element is the local location.
*
* @var Aray
*/
private $data;
/**
* A body object
*
* It contains a GeoBody value when the global location is a body
* ie if $this->data[0][0] == 'B'
*
* Otherwise, its value is null.
*
* @var GeoBody
*/
public $body = null;
/**
* A place object
*
* It contains a GeoPlacevalue when the global location is a place
* ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9
*
* Otherwise, its value is null.
*
* @var GeoPlace
*/
public $place = null;
/**
* A point identified by x, y, z coordinates
*
* @var GeoPoint3D
*/
public $point3D = null;
/**
* A ship object
*
* It contains a Ship value when the global location is a ship
* ie if $this->data[0][0] == 'S'
*
* Otherwise, its value is null.
*
* @var Ship
*/
public $ship = null;
/**
* Initializes a new location instance
*
* @param string $global the global location
* @param string local the locallocation
*
* @todo improve local location handling
*/
function __construct ($global = null, $local = null) {
if (!$global) {
$this->data = array();
} elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/[BS][0-9]{5}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/^xyz\:/", $global)) {
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->data[0] = $global;
} else {
throw new Exception("Invalid expression: $global");
}
} else {
global $db;
$name = $db->sql_escape($global);
$sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
$code = $db->sql_query_express($sql);
if ($code) {
$this->data[0] = $code;
return;
}
throw new Exception("Invalid expression: $global");
}
//TODO: handle $local in a better way: from the global location, gets
//a local location handler. Or a some inheriance, like a class
//HypershipGeoLocation extending GeoLocation.
if ($local !== null) $this->data[1] = $local;
$this->load_classes();
}
/**
* Gets $place, $body and $ship instances if they're needed
*/
function load_classes () {
//No data, no class to load
if (!count($this->data))
return;
//Loads global classes
$global = $this->data[0];
$code = substr($global, 1, 5);
switch ($global[0]) {
case 'B':
switch (strlen($global)) {
case 9:
$this->place = GeoPlace::from_code($global);
case 6:
$this->body = new GeoBody($code);
break;
}
break;
case 'S':
$this->ship = new Ship($code);
break;
case 'x':
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
}
break;
}
}
/**
* Magic method called when a unknown property is get.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code,
* $body_kind, $containsGlobalLocation, $containsLocalLocation.
*/
function __get ($variable) {
switch ($variable) {
/* main variables */
case 'global':
return $this->data[0];
break;
case 'local':
return (count($this->data) > 1) ? $this->data[1] : null;
break;
/* global location */
case 'type':
return $this->data[0][0];
case 'body_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 1, 5);
}
return null;
case 'place_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 6, 3);
}
return null;
case 'ship_code':
if ($this->data[0][0] == 'S') {
return substr($this->data[0], 1, 5);
}
return null;
case 'body_kind':
if ($this->data[0][0] == 'B' && $this->body != null) {
if ($kind = $this->body->kind()) {
return $kind;
}
} elseif ($this->data[0][0] == 'S') {
return 'ship';
}
return 'place';
case 'containsGlobalLocation':
return count($this->data) > 0;
case 'containsLocalLocation':
return count($this->data) > 1;
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
/**
* Checks if the place exists
*
* @return bool true if the place exists ; otherwise, false.
*
* @todo handles alias
*/
function exists () {
$n = count($this->data);
//If not defined, it doesn't exist
if ($n == 0) return false;
//Checks global location
switch ($this->data[0][0]) {
case 'B':
switch (strlen($this->data[0])) {
case 9:
if (!$place = GeoPlace::from_code($this->data[0]))
return false;
break;
case 6:
$body = new GeoBody(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
break;
case 'S':
$ship = new Ship(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
return false;
}
if ($n > 1) {
if (!isset($place)) {
message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
if (!$place->is_valid_local_location($this->data[1])) {
return false;
}
}
return true;
}
/**
* Checks if the place is equals at the specified expression or place
*
* @return bool true if the places are equals ; otherwise, false.
*
* @todo Create a better set of rules to define when 2 locations are equall.
*/
function equals ($expression) {
//Are global location equals?
//TODO: create a better set of rules to define when 2 locations are equa l.
if (is_a($expression, 'GeoLocation')) {
if (!$this->equals($expression->data[0])) {
return false;
}
if (count($expression->data) + count($this->data) > 2) {
return $expression->data[1] == $this->data[1];
}
}
if ($expression == $this->data[0]) return true;
$n1 = strlen($expression);
$n2 = strlen($this->data[0]);
if ($n1 > $n2) {
return substr($expression, 0, $n2) == $this->data[0];
}
return false;
}
/**
* Represents the current location instance as a string
*
* @return string a string representing the current location
*/
function __toString () {
if (!$this->data[0])
return "";
switch ($this->data[0][0]) {
case 'S':
$ship = new Ship($this->ship_code);
$location[] = $ship->name;
break;
case 'B':
$body = new GeoBody($this->body_code);
$location[] = $body->name ? $body->name : lang_get('UnknownBody');
if (strlen($this->data[0]) == 9) {
$place = GeoPlace::from_code($this->data[0]);
$location[] = $place->name ? $place->name : lang_get('UnknownPlace');
}
break;
+
+ case 'x':
+ $pt = $this->point3D->to_spherical();
+ return sprintf("(%d, %d°, %d°)", $pt[0], $pt[1], $pt[2]);
default:
message_die(GENERAL_ERROR, "Unknown location identifier: $type.<br />Expected: B or S.");
}
return implode(", ", array_reverse($location));
}
/**
* Magic method called when a unknown property is set.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code
*/
function __set ($variable, $value) {
switch ($variable) {
/* main variables */
case 'global':
$this->data[0] = $value;
break;
case 'local':
$this->data[1] = $value;
break;
/* global location */
case 'type':
if ($value == 'B' || $value == 'S') {
if (!$this->data[0]) {
$this->data[0] = $value;
} else {
$this->data[0][0] = $value;
}
}
break;
case 'body_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "B" . $value;
return;
} elseif ($this->data[0][0] == 'B') {
$this->data[0] = "B" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a body.");
}
throw new Exception("$value isn't a valid body code");
case 'ship_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "S" . $value;
return;
} elseif ($this->data[0][0] == 'S') {
$this->data[0] = "S" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a ship.");
}
throw new Exception("$value isn't a valid ship code");
case 'place_code':
if (!preg_match("/[0-9]{1,3}/", $value)) {
throw new Exception("$value isn't a valid place code");
}
$value = sprintf("%03d", $value);
if ($this->data[0][0] == 'B') {
$this->data[0] = substr($this->data[0], 0, 6) . $value;
}
throw new Exception("Global location isn't a body.");
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
}
?>
diff --git a/includes/geo/point3D.php b/includes/geo/point3D.php
index 2cadc83..ccd9ec8 100644
--- a/includes/geo/point3D.php
+++ b/includes/geo/point3D.php
@@ -1,210 +1,241 @@
<?php
/**
* Geo point 3D class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-23 14:14 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
+require_once("galaxy.php");
+
/**
* Geo point 3D class.
*
* This class represents a x, y, z point.
*
* It implements IteratorAggregate to allow the foreach instruction
* on a GeoPoint3D object:
*
* <code>
* $point = new GeoPoint3D(17, 24, -6);
* foreach ($point as $axis => $coordinate) {
* echo "\n\t$axis = $coordinate";
* }
* //This will output:
* // x = 17
* // y = 24
* // z = -6
* </code>
*
* The point 3D representation is xyz: [x, y, z] ; you can print it as a string
* and get this format:
*
* <code>
* $point = new GeoPoint3D(17, 24, -6);
* echo (string)$point; //will output xyz: [17, 24, -6]
* </code>
*
*/
class GeoPoint3D implements IteratorAggregate {
//
// x, y, z public properties
//
/**
* the x coordinate
*
* @var integer
*/
public $x;
/**
* the y coordinate
*
* @var integer
*/
public $y;
/**
* the z coordinate
*
* @var integer
*/
public $z;
//
// constructor / toString
//
/**
* Initializes a new instance of GeoPoint3D class
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
*/
function __construct ($x, $y, $z) {
$this->x = (int)$x;
$this->y = (int)$y;
$this->z = (int)$z;
}
-
+
/**
- * Parses a xyz: [x, y, z] string expression ang gets a GeoPoint3D object
+ * Parses a string expression ang gets a GeoPoint3D object
+ *
+ * Formats recognized are:
+ * - xyz: [x, y, z]
+ * - (x, y, z)
*
* @param string $expression the expression to parse
* @return GeoPoint3D If the specified expression could be parsed, a GeoPoint3D instance ; otherwise, null.
*/
static function fromString ($expression) {
if (string_starts_with($expression, 'xyz:', false)) {
$pos1 = strpos($expression, '[', 4) + 1;
$pos2 = strpos($expression, ']', $pos1);
if ($pos1 > -1 && $pos2 > -1) {
$expression = substr($expression, $pos1, $pos2 - $pos1);
$xyz = explode(',', $expression, 3);
return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
}
+ } elseif ($expression[0] = '(') {
+ $expression = substr($expression, 1, -1);
+ $xyz = explode(',', $expression, 3);
+ return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
}
return null;
}
-
+
+ /**
+ * Returns a string representation of the point coordinates.
+ *
+ * @param $format the format to use
+ * @return string a string representation of the coordinates
+ *
+ * To print a "xyz: [10, 20, 40]" string:
+ * $point = new GeoPoint3D(10, 20, 40);
+ * echo $point->sprintf("xyz: [%d, %d, %d]");
+ *
+ * //Of course, you could have (implicitely) use the __toString method:
+ * echo $point;
+ *
+ * To print a (10, 20, 40) string:
+ * $point = new GeoPoint3D(10, 20, 40);
+ * echo $point->sprintf("(%d, %d, %d)");
+ */
+ function sprintf ($format) {
+ return sprintf($format, $this->x, $this->y, $this->z);
+ }
+
/**
* Returns a xyz: [x, y, z] string representation of the point coordinates.
*
* @return string a xyz: [x, y, z] string representation of the coordinates
*/
function __toString () {
- return sprintf("xyz: [%d, %d, %d]", $this->x, $this->y, $this->z);
+ return $this->sprintf("xyz: [%d, %d, %d]");
}
-
+
/**
* Determines if this point is equal to the specified point.
- *
+ *
* @param GeoPoint3D $point The point to compare
* @return bool true if the two points are equal ; otherwise, false.
*/
function equals ($point) {
return ($this->x == $point->x) && ($this->y == $point->y) && ($this->z == $point->z);
}
//
// Math
//
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
*
* The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function to_spherical () {
return GeoGalaxy::cartesian_to_spherical($this->x, $this->y, $this->z);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
*
* The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function to_spherical2 () {
return GeoGalaxy::cartesian_to_spherical2($this->x, $this->y, $this->z);
}
/**
* Translates the center and rescales.
*
* This method allow to help to represent coordinate in a new system
*
* This method is used to represent Zed objects in dojo with the following
* parameters:
* <code>
* $pointKaos = GeoPoint3D(800, 42, 220);
* $pointKaos->translate(500, 300, 200, 2);
* echo $pointKaos;
* //This will output xyz: [150, -129, 10]
* </code>
*
* @param int $dx the difference between the old x and new x (ie the value of x = 0 in the new system)
* @param int $dy the difference between the old y and new y (ie the value of y = 0 in the new system)
* @param int $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
* @param float $scale if specified, divides each coordinate by this value (optional)
*/
function translate ($dx, $dy, $dz, $scale = 1) {
if ($scale == 1) {
$this->x += $dx;
$this->y += $dy;
$this->z += $dz;
} elseif ($scale == 0) {
$this->x = 0;
$this->y = 0;
$this->z = 0;
} else {
$this->x = $this->x * $scale + $dx;
$this->y = $this->y * $scale + $dy;
$this->z = $this->z * $scale + $dz;
}
}
//
// Implementing IteratorAggregate
//
/**
* Retrieves class iterator. It traverses x, y and z.
*
* @return Traversable the iterator
*/
function getIterator () {
return new ArrayIterator($this);
}
}
?>
diff --git a/includes/geo/scene.php b/includes/geo/scene.php
index f82b452..bc9d4ee 100644
--- a/includes/geo/scene.php
+++ b/includes/geo/scene.php
@@ -1,191 +1,244 @@
<?php
/**
* Geo scene class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
- * 0.1 2010-01-30 17:42 DcK
- *
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('location.php');
require_once('octocube.php');
+require_once('sceneindex.php');
if (!defined('SCENE_DIR')) {
/**
* The directory containing scenes files
*/
define('SCENE_DIR', 'content/scenes');
}
/**
* Geo scene class
*
* This class provides methods to determine and renders the local scene.
*/
class GeoScene {
/**
* Last error or warning
*
* @var string
*/
public $lastError;
/**
* File scene to serve
*
* @var string
*/
public $sceneFile;
/**
* The location of the scene to print
*
* @var GeoLocation
*/
public $location;
/**
* Initializes a new GeoScene instance
*
* @param GeoLocation $location location the scene is to print
*/
function __construct ($location) {
$this->location = $location;
//Gets local scene
if ($location->containsLocalLocation) {
if ($this->get_local_scene()) return;
}
//Gets global scene
if ($location->containsGlobalLocation) {
if ($this->get_global_scene()) return;
}
//If not scene found, let's set a warning
$this->lastError = "No scene found.";
}
/**
* Gets local scene
*
* @return boolean true if a scene have been found ; otherwise, false.
*/
private function get_local_scene () {
+ //From the index
+ $index = GeoSceneIndex::Load(SCENE_DIR);
+ if ($tpl = $index->get_local_template($this->location->global, $this->location->local)) {
+ $this->sceneFile = SCENE_DIR . '/' . $tpl;
+ return true;
+ }
+
+ //From filename
+ $expression = $this->location->global . ' ' . $this->location->local;
+ if ($this->try_get_scene($expression)) {
+ return true;
+ }
return false;
}
/**
* Gets global scene
*
* @return boolean true if a scene have been found ; otherwise, false.
*/
private function get_global_scene () {
$location = $this->location;
if ($location->place) {
if ($this->try_get_scene($location->global)) {
return true;
}
}
if ($location->body) {
if ($this->try_get_scene('B' . $location->body->code)) {
return true;
}
}
return false;
}
/**
* Gets file extension
*
* @param string $file the file path
* @return string the file extension
*/
public static function get_file_extension ($file) {
$pathinfo = pathinfo($file);
return $pathinfo['extension'];
}
/**
* Renders the file
*
* @todo Add standard code to render .swf Flash/ShockWave files.
*/
public function render () {
if ($file = $this->sceneFile) {
switch ($ext = GeoScene::get_file_extension($file)) {
case 'png':
case 'jpg':
case 'gif':
case 'bmp':
echo "<img src=\"$file\" />";
break;
case 'tpl':
global $smarty;
$template_dir = $smarty->template_dir;
$smarty->template_dir = getcwd();
//$this->location is the object reference
//Some objects like the hypership move, so we also need to know where there are.
//From the template, this object location is assigned to $location
//To get $this->location from template, use $CurrentPerso->location
if ($this->location->body) {
$smarty->assign("location", new GeoLocation($this->location->body->location));
} elseif ($this->location->ship) {
$smarty->assign("location", new GeoLocation($this->location->ship->location));
}
$smarty->assign("SCENE_URL", defined('SCENE_URL') ? SCENE_URL : '/' . SCENE_DIR);
lang_load('scenes.conf', $this->location->global);
$smarty->display($file);
$smarty->template_dir = $template_dir;
break;
case 'php':
message_die(HACK_ERROR, ".php scene files not allowed without review", '', __LINE__, __FILE__);
default:
message_die(GENERAL_ERROR, "Can't handle $ext extension for $file scene", 'GeoScene render error', __LINE__, __FILE__);
}
echo "\n\n";
}
}
/**
* Tries to get the scene file.
*
* It will tries to find in the scene directory a file with $code as name,
* and .tpl .png .gif .bmp .swf .html or .php as extension.
*
* @param string the location code (and filename)
* @return bool true if a scene file have been found and set ; otherwise, false.
*/
private function try_get_scene ($code) {
$file = SCENE_DIR . "/$code";
$extensions = array('tpl', 'png', 'jpg', 'gif', 'bmp', 'swf', 'html', 'php');
foreach ($extensions as $ext) {
if (file_exists("$file.$ext")) {
$this->sceneFile = "$file.$ext";
return true;
}
}
return false;
}
+
+ /**
+ * Reads scene templates and indexes information
+ */
+ public static function index_scene_templates (&$global_templates, &$local_templates, &$updated) {
+ $global_templates = array();
+ $local_templates = array();
+ $updated = filemtime(SCENE_DIR);
+ if ($handle = opendir(SCENE_DIR)) {
+ while (false !== ($file = readdir($handle))) {
+ if (GeoScene::get_file_extension($file) == 'tpl') {
+ $template = file_get_contents(SCENE_DIR . '/' . $file, false, NULL, 0, 1024);
+ $location = self::get_template_location($template);
+ if ($location[1] == NULL) {
+ $global_templates[$location[0]] = $file;
+ } else {
+ $local_templates[$location[0]][$location[1]] = $file;
+ }
+ }
+ }
+ closedir($handle);
+ }
+ }
+
+ private static function get_template_location ($template) {
+ $location = array(NULL, NULL);
+
+ //Gets global location
+ $pos1 = strpos($template, "Global location: ") + 17;
+ $pos2 = strpos($template, "\n", $pos1);
+ $location[0] = trim(substr($template, $pos1, $pos2 - $pos1));
+
+ //Gets local location
+ $pos1 = strpos($template, "Local location: ");
+ if ($pos1 !== false) {
+ $pos1 += 16;
+ $pos2 = strpos($template, "\n", $pos1);
+ $location[1] = trim(substr($template, $pos1, $pos2 - $pos1));
+ }
+
+ return $location;
+ }
}
-?>
+?>
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 11, 11:25 (2 w, 3 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
21134
Default Alt Text
(71 KB)

Event Timeline