Google Maps uses a mixture of PHP,MySQL,JavaScript, and DHTML to plot
players,quests,hotspots, on the map based on the lat/lon of the player/quest/hotspot.
Google Maps requires a certain directory to be registered when
requesting a key, so files outside that directory will not work.
In this case, if you try to run any google map implementations
outside of unexceptional.net/blog/maps, the page will not work.
For each of the $<VARNAME> = <VALUE> i.e.
[$LOCALVIEW = 0;], these are the values setinside each of
the php files for each type of view and the value associated with it. See each section
for more information.
When using the XMaps library, the following modifications must be made:
in the init() function
toggleVisibility('key','show','visible','visible'); must be renamed to
toggleVisibility('key1','show','visible','visible');
similarly, in the div:
<div id="key" style="visibility:hidden"> must be renamed to
<div id="key1" style="visibility:hidden">
this is to prevent a javascript error in IE when the xmap library searches
for variable "key" and gets the div layer instead of the styles associated
with the xmap line / polygon / etc.
Index.php is the default view visible to the player when google
maps normally loads. Index.php is responsible for showing
static information about where the player is with respect to
Guy, other players, and to quests. Each of the different views
of index.php provide functionality to tell where the player is
with respect to another object [player,quest,etc].
$LOCALVIEW = 0;
Local View is the default view that loads when you enter the blog.
This view centers and zooms around the player, and draws a line
from where the player is to where Guy is. This way, the player
has an idea of how far he is to Guy and in which direction.
$GLOBALVIEW = 1;
Global View is the view when the player zooms all the way out of
Google Maps. This is the world view where you see all the players
that are in the game and where they are situated in the world.
$SPECIFICPLAYER = 2;
When in local / global view, if you click on a specific player, a
window popups that gives you various options. If you click on
"current position" this view is toggled. You will see 2 players:
yourself and the other player you selected, with a line drawn
between the two. The map auto zooms to the correct level so that
both players are visible at the same time.
$QUEST = 3;
When a player clicks on a quest from his available,completed,active
list, an option is presented to show where the destination is.
Clicking this toggles the quest view, where the player and the quest
are shown on the same screen with a line drawn between them.
If a player is significantly far from a quest location, he is provided
with an option to fly / take a bus to that location. For both travel
methods, there are various ticket prices, each price offering positive
and negative effects. For example, if a player decides to take a
Stowaway trip, he has to possibility arrive in an
unintended destination, but has the ability to gain items (from rummaging
through the luggages in the cargo bay). The other effects are listed
side the index.php file and is upto the players to discover.
Back To Top
Tracker.php, as it implies, is used to track player movements. It
has a dynamic mode, as well as several static modes, displaying
where the player has travelled sinced when he/she registered.
$LASTWAYPOINTS = 0;
Last Waypoints plots the last <X> waypoints (where <X> is determined
by the maxPlotPoints in the prefs db table) from the player. Each
point pulled from the database is given a marker icon which when
moused over, reveals the lat/lon/timestamp of that logpoint.
$LIVETRACKING = 1;
Live Tracking mode allows you to see real time updates of where a
player is moving provided he is either running the GPSPlotter or
DickHunt on the cell phone and his lat/lon are updating.
This mode uses the help of logpoint.php to continually poll the
database for new results w/o the need to meta-refresh the entire
google map pages. The reasoning behind this is that to constantly
reload the google map page is both time consuming and taxing on the
Google Servers and the players bandwidth, so only the necessary
amount of data needed to be refreshed is used.
Inside logpoint.php all pulled data is converted to a javascript
format so that tracker.php can access it. Logpoint.php is embedded
into tracker.php both as an include(), and as a hidden iframe named
innerlog, so that when tracker.php wants new points from the db, it
uses javascript to replaces its own points with innerlog's points
(wpoints = innerlog.wpoints)
Live Tracking updates every <X> seconds, (<X> is relative to the
value stored in playerUpdateInterval in the prefs db table). When
this happens, the last 2 newest waypoints are pulled from the db.
If the points differ from the last points currently plotted, they
are added to the list and the path is redrawn.
Back To Top
Logpoint.php is a complementary tool to tracker.php. It polls
the database to see all the lat/lon locations of all players
to see if any of them have moved. Tracker.php calls on logpoint.php
to gather changes to player locations via the database activity, then
acts accordingly.
$LIVETRACKING = 10;
Notice how
$LIVETRACKING in logpoint.php is 10, but only 1
in tracker.php. This is because since the type is in the
$HTTP_POST_VARS,
if both values were the same, the code in logpoint.php would execute and cause problems
with tracker.php (tracker.php includes logpoint.php). Thus, it is scaled by 10.
This mode basically polls and pulls data from the db every <X> seconds
(again relative to the value in the prefs db), then generates JavaScript
code that structures the information (lat,lon,timestamp,playerID,etc)
so that tracker.php can effectively use it.
$PLAYERHISTORY = 20;
(See above Live Tracking Notes)
Back To Top
Radius.php is used by the plot_mngr to display where hotspots,regions,and
quests are. It is useful for the developer to know exactly how large
and how far apart 2 hotspots/regions/quests are from each other.
Radius.php makes use of XMaps static variables for distance and drawing circles.
Refer to the XMaps documentation for the various XDistance units of
measurements (FT,MI,KM,etc)
$HOTSPOTZONE = 3;
Plots all hotspot zones, or a specific hotspot zone, measured in feet
$REGIONZONE = 4;
Plots all region zones or a specific region zone, measured in miles
$QUESTZONE = 5;
Plots all quest zones or a specific quest zone, measured in feet
$ALLZONE = 6;
Plots all of the above
$SELECTEDZONE = 7;
Plots <X> hotspots, <Y> regions, and <Z> quest zones where <X>,<Y>,<Z>
are user selected zones from the hotspot,region, and quest list
Each hotspot/region/quest list is a comma deliminated set of ids and the three lists are
joined together with a period. The order of the final string must be
[hotspots].[regions].[quests]
Otherwise they will fail to plot properly and google maps will appear grey
Back To Top
Plot Manager is used by developers to see all created hotspots,regions, and quests
lat / lon locations as well as the radius of each. Plot Manager contains several
select boxes that list all existing hotspots, regions, and gps quests. You simply
select all hotspots,regions,quests you want mapped out then click the view button
and a popup google map using radius.php will show all the mapped out points. If you
wish to deselect items, either clear all selects via the clear button, or use ctrl-click
to deselect individual items.
Back To Top
http://www.toeat.com/scripts/gxmarker.1.js
JavaScript library used to create the popup boxes on mouse over. Simply define a new marker as a
GxMarker instead of the default google map GMarker. Then add a EventListener for "onmouseover"
var marker = new GxMarker(point);
GEvent.addListener(marker,"mouseover",function()
{
[insert code here]
});
Back To Top
http://xmaps.busmonster.com/
JavaScript library for creating and filling circles on google maps. Just add an overlay to
the map using the constructor to create a circle from XMaps
var scale = XDistance.FT;
// patterns to define the fill and outline style, pattern[x,y] means it will draw x pixels
// then skip y pixels, then draw x pixels, and repeat until the circle is filled
var outlineStyle = {color:'#111122',opacity:.9,pattern:[5,10],weight:3};
var fillStyle = {color:'#99ffff',opacity:.4};
// Google Maps GPoint accepts it as (lon,lat)
var center = new GPoint([lon], [lat]);
var radius = new XDistance(zone[i][4], scale);
map.addOverlay(XPolygon.createRegularPolygonFromRadius(center, radius, 36, 0, outlineStyle, fillStyle));
See XMaps documentation for more info
Back To Top
http://www.google.com/apis/maps/documentation/
In order to use google maps on your site, you must first register for a key to use on our website.
http://www.google.com/apis/maps/signup.html
Keep in mind that the key is specific to whatever directory you signed up for, so if you
decide to move the directory later on, your key may become invalidated and no longer work.
If you register your key using [hostname/maps] and then decide to switch it to [hostname/visuals]
the key will not work. Similarly, if you move hosts [www.guy.com] to [www.guy.org] the key will
no longer work.
An overview of all google map components as well as a tutorial can be found on their API documentation website.
Back To Top
Talk Quest and Grammar uses PHP,MySQL, and Java to select which phrases
are recognized and interprets what the player says and performs the related
action associated w/ what the player says (i.e. Player says "Drop Book"
and the book is removed from inventory in db).
A GPS signal is sent by the phone every 45 seconds, which updates the players location.
This GPS coordinate is used by Varuna to determine if a player is near a hotspot and
generate a call if necessary.
Please note that there is a certain level of ambiguity whenever the keyword
varuna is used. Varuna is a daemon that polls
for player location i.e. [varuna.php / Varuna.java]
as well as the name of the automated voice callbot heard whenever a player
answers a call [Asterisk / Varuna]. Varuna as a
daemon will be referred to as Varuna and Varuna
as the callbot will be referred to as Asterisk / Varuna.
** NOTE ** There exists 2 versions of Varuna which do the same thing,
varuna.php and Varuna.java. The reasons for this is because the original
implementation (varuna.php) was highly unstable and would crash for no
reason. Thus it was ported to Java, to run. From [12.06.05] varuna.php
is no longer being updated if Varuna.java changes.
Varuna is a daemon that runs, checking if players are near hotspots, and
gives that player a call if he/she enters the hotspot, so that the
player can perform special actions at that hotspot.
Varuna works by polling the player's current_waypoint to see if the player
is near other players or hotspots. If the player is, he will be given a
phone call unless he already has a phone call in place. This can happen
b/c a player is near 2 players at the same time, or there are overlaping
hotspot radius. This way, the player does not get several phone calls from
asterisk at the same time.
When a player recieves a call, the locked field will be set to 1 this is
to prevent multiple phone calls from the same hotspot. Otherwise you will
receive consecutive phone calls until you walk out of the hotspot
(Personally received 36 consecutive phone calls / missed calls while in
a hotspot before this fix was added)
If a player who is currently in a hotspot or near a player moves out of
the hotspot radius, his locked field will be set to 0. This way players
can receive phone calls again. This also forces the player to move a bit
(in and out of a hotspot) to get a call from varuna.
STEAL / PLAYER NOTES [when trying to steal from players]
When a player is near another player, it is not 100% certain he will receive
a call. He will either receive a call, not receive a call, or be locked from
receiving a call. The same thing will happen to the other player he is near.
This makes it so 2 players will not be trying to steal from each other at the
same time (although it is possible, it is not 100%).
The difference between not receiving a call and locked from receiving a call
is that even if a player doesn't receive a call, after <X> seconds (poll delay
to check if players are near hotspots) he may be given a call again. Thus, if
you follow a player long enough or are near him long enough, you may receive a
call, even if it is not immediate. However, if a player is locked from a call,
the player must move away from the target player until his locked status is
set to 0 before being able to receive a call.
This makes it so you either immediately get a call, wait some turns before
you get a call, or lose the chance to get a call.
Back To Top
** NOTE ** The functionality of GET <X> BURGERS (<X> is a number corresponding to how many
burgers you wish to get) was removed from because the accuracy ratios degenerated
tremendously when a number value was added. This was then replaced with a
random amount of items added whenever GET BURGERS was stated.
Varuna Talker is the script that is run whevenever the player answers the phone
(or when a developer calls Varuna/Asterisk). It is the mechanism in which
Asterisk/Varuna interacts with the player. The generic actions Varuna Talker
does are:
1 - check player location,
2 - display any actions possible at that location,
3 - ask for player command,
4 - process command,
5 - repeat steps 2 - 4
Varuna Talker currently has 3 different cases in which interpretation is done:
hotspot mode, steal mode, and nowhere mode
The 3 modes all have different grammars associated with them although each
grammar is set to the same file digits<X>.gram (where <X> is the playerID).
In any mode, when the player says QUIT, the system will ask whether he wishes
to quit or not (YES or NO). if YES, then the system quits, otherwise it returns
to whatever mode the player was in.
This is done by backing up digits<X>.gram to backup<X>.gram, then replacing
digits<X>.gram with a grammar that only recognizes YES or NO. Then either
varuna_talker quits (b/c of the YES command) or copies back backup<X>.gram
into digits<X>.gram.
When a player receives a phone call, he can only say <X> commands (<X> is
currently 6, but may change) before the phone call ends. In the event it is
in steal mode, <X> becomes 3. This is done for 2 reasons:
1) In steal mode, it is done to prevent the player from emptying out the
target's inventory by endlessly trying to steal
2) Normally, if a player hangs up the phone w/o saying QUIT, asterisk and
varuna_talker will not be able to detect this and will continue to try
to process the player commands. By limiting the number of commands,
it is a escape mechanism to prevent the system from tying up resources
by keeping the connection active and trying to interpret commands.
Otherwise, the process will be kept alive and running forever until a
sys admin terminates it.
HOTSPOT
If a player is near a hotspot, then the hotspotID in the player db table
will be a positive number (1 and greater).
The generated grammar is based on what items are available at that hotspot
and what actions are selected for that item. These are set in the
talk_quest_mngr.php content creation tool.
When a player says GET <X> (<X> is an item) a randomly generated amount betw
1 and 5 items are added to the player inventory. The next time he says
GET <X> (within the same phone call), it will say there are no <X> in that
area. This makes it so that in one phone call, the player can only pick
up a set amount of items, instead of being able to infinitely max out his
inventory.
The USE command has low recognition w/i the Sphinx System, so each item will
have its distinct USE command (EAT BURGERS, DRINK BEER, etc). When you USE
an item, the affected stats will be spoken back to the player
STEAL
When a player is called b/c he is near another player, the steal mode of
varuna_talker is activated. In this mode, the hotspotID becames a negative
value (-1 and lower). This value represents the playerID (player that will
be stolen from).
In trying to steal from the player, a successful steal is not 100% certain.
there are various results that may happen (based on the random number and
percentages of each result) (See ActionSTEAL.java below for more info)
As stated above, in this mode, there are only 3 chances to steal from a
player. The lowered amount is to prevent a player from stealing everything
a player has as well as to keep it semi realistic, since the more you steal
the more dangerous it becomes to being caught, so after 3 tries, you leave
The 3 chances to steal don't take into account when QUIT is accidentally
said or when Sphinx doesn't recognize what the player says.
NOWHERE
This mode is only active for developers, or if someone tries to call back to
varuna. When a player is not near a hotspot or player, varuna.php will set
his hotspotID to 0. So when the player calls, he is nowhere near a hotspot
so there are no associated actions or items in the nonexistant hotspot.
Normally stated actions (GET BURGERS,etc) will not be recognized and the
only commands recognized are ACTIVATE and QUIT
The ACTIVATE command is a hidden phrase for developers to instantly teleport
the DEV ZONE hotspot to where the player making the phone call is. This is
done so that if the developer calls in again, he will be automatically at the
dev zone.
This dev zone allows a developer to show off and test the functionality of
the voice recognition system. After activating the DEV ZONE, this mode
functions exactly like HOTSPOT mode.
Back To Top
A callfile is generated for the players which in turns executes this script.
The callfile is created upon registration, when the player changes his/her number,
or when the player updates his/her account and hasn't previously activated his number.
This script allows players either to activate their number by saying ACTIVATE, or
remove themselves from the database by saying CANCEL
Back To Top
PrankBot a.k.a. CallBot, is the mechanism in which players can send customized messages
to other players. One just needs to select the player from the list of players, then
type a customed message to that player in order for him/her to receive it (provided that
other player answers the phone). Do not worry about the phone number field being
hidden. In order to protect the player's information, the number is kept hidden.
Alternatively, you can just type the number of the person you wish to call (if you want
to call a non player and tell them about unexceptional.net this is how to do it).
An optional field, Date:, allows you to set when you want the player to received the call.
This field must follow the format [
YYYY-MM-DD hh:mm:ss] (year-month-day hour:min:sec)
Note that hour (hh) must be in 24 hr interval (0-23) instead of 12 hr interval (1-12). The call
will be made when the clock reaches the designated Date and Time (PST) on Asterisk / Varuna.
Please be aware there is a Terms of Service / Disclaimer you must read and abide to
in order to use prankbot.
Due to costs associated with making the calls, there may be times when CallBot is disabled for public
use. When this happens, users must wait till the start of the next month before CallBot is available
Prankbot Talker is the Asterisk / Varuna script that basically speaks whatever the user typed as a message.
Please be aware that the voice synthesis software is very sensitive and many slang / abbreviations / etc.
may be in appropriately pronounced. For best results, keep the sentences short and make use of punctuation.
Added to the end of every prank call is a friendly reminder that this service has been brought to you by
unexceptional.net
Back To Top
Grammar.php is the library that creates the necessary digits<X>.gram
files needed by Sphinx to know what the legal grammars are. Whenever a
function in grammar.php is called, a specific grammar related to the
function is generated.
Grammar.php has several functions that generate the respective grammars for each
of the varuna_talker modes.
function createGramFile($playerID,$hotspotID,$escapeWord)
* generates the grammar for a specific hotspot
* used in varuna_talker.php during HOTSPOT MODE
function createDevGramFile($playerID,$escapeWord,$devWord)
* generates the grammar for activating the DEV ZONE
* used in varuna_talker.php during NOWHERE MODE
function createPlayerGramFile($playerID,$targetID,$escapeWord)
* generates the grammar for stealing from other players
* only selects items that the target player has, excluding any hidden (not visible) items or quest keys
* used in varuna_talker.php during STEAL MODE
function createConfirmGramFile($playerID)
* generates the grammar for YES / NO confirmation
* used in varuna_talker.php whenever player says QUIT
function createActivationGramFile($playerID)
* generates the grammar for ACTIVATE / CANCEL confirmation
* used in activation_talker.php for players trying to activate their phone numbers
Back To Top
talk_quest_mngr is the content creation tool for adding/editing talk quests.
These talk_quests are specific hotspots (a lat/lon location and a radius)
placed around the world so that when a player enters the hotspot, a call
is made to that player indicating he/she is in a hotspot.
There are 4 specific tables associated with talk_quests.
talk_quests
* quests contain hotspots, although this is currently not used
talk_hotspots
* in each hotspot, there are items linked to it
* the items are those found in inventory_mngr.php
items
* each item has associated actions that are valid (eat,drop,get,etc)
talk_actions
* actions are a list of unique commands the player can say are are
linked to items
Two tables are associated with each other with a 3rd table in the format of
talk_<X>_<Y>_list where <X> and <Y> are the table names
i.e. (
talk_hotspot_item_list or
talk_item_action_list)
Whenever a new action is created, a default template for that action
Action<X>.java is created so that the textparser can translate what the
player says to actual backend actions in the db.
These Action<X>.java files must be defined / coded by the developer
Back To Top
Hotspots are a region defined by a gps coordinate and a radius. Inside each defined
hotspot are a list of actions that can be performed in that hotspot. These are set
using the talk_quest_mngr. When a player enters a hotspot, he will receive a call
from varuna. Varuna will speak all commands associated with that hotspot
(as defined by the grammar file and talk_quest_mngr). The player then speak a certain
command. This command (GET BEER) is then interpreted by Sphinx. Varuna will then
say what it thinks the player says, and as well as the effect the command (YOU GOT 1 BEER).
Voice Recognition is done by Sphinx, Voice Synthesis is done by Festival.
There are 2 types of hotspots, static hotspots and dynamic hotspots. Static hotspots are
regions that generally don't move unless the developer changes it (i.e. SECRET GARDEN).
Dynamic hotspots are the areas surrounding each individual player. Each player is considered
a dynamic hotspot and has a set of actions tied to them. These actions are defined by the
type of items the player has in his inventory. Players are considered dynamic hotspots because
the location of the hotspot changes as the player's location change.
Back To Top
http://cmusphinx.sourceforge.net
Sphinx is the voice recognition system for detecting what the player says and
returning it as a string.
Inside WavFile.java there are 2 modes of operation, daemon and single
In running sphinx, users may notice an extreme overhead between when the program
is launched, to when actual results are returned. This is because of the need to
load the entire dictionary and related parsing files into memory before actual
interpretation can occur. This is the reason why the 2 modes were created.
On average, a single run of sphinx can take between 15 - 20 seconds before actual
results are returned. This is highly unacceptable for the user to be put on hold
for that long.
However in daemon mode, the interpretation takes only 3 - 5 seconds. The main
reason for this difference is the overhead of loading the dictionary. Once daemon
mode is launched and the dictionary files are loaded, the actual interpretation
is relatively quick.
So when deamon mode is first launched, there will be a 12 second overhead before
actual interpretation can occur.
Basic execution of Sphinx is done via the cmd line
java -mx256m demo.sphinx.wavfile.WavFile [wavfile filename]
The -mx256m flag sets how much memory is allocated for sphinx in parsing. Without
this flag, Sphinx will crash and quit due to not enough memory
Daemon Mode - Usage:
java -mx256m demo.sphinx.wavfile.WavFile
In this mode, searches for files that follow a specific format, as defined
in WavFileFilter.java
The format is any files that match result_converted<X>.wav where <X> is
the playerID of whoever said the command
After finding any matching files, it will load the grammar for that player
as defined by <X>. This way, interpretation is related to what the player
says. After loading the grammar, sphinx will try to parse and store the
result in spinx_output<X>.txt
This daemon will run infinitely every 3 seconds until it is shut down
Single Mode - Usage:
java -mx256m demo.sphinx.wavfile.WavFile result_converted<X>.wav
Single mode exists as a fail safe in the event deamon mode shuts down
This mode does the exact same thing as deamon mode, except instead of
search for all matching files, the specific file is passed as an argument
and only that file is interpreted. The player's associated grammar file
is still loaded.
As noted, single mode is much slower than daemon mode and is only used
when daemon mode shuts down
Back To Top
The varuna log file contains a log of all actions that occur whenever the varuna
daemon is launched. This log file shows the time and date whenever a player is
given a call, as well as when players enter or leave hotspots. It is useful for
debugging to see if everything is working.
Back To Top
Everytime a player says an action, it is logged inside the player log file. The
4 types of information it logs are:
Timestamp
Sphinx Results
Varuna Talker command line
Text Parser Results
Example Log:
2005-11-29 19:17:27
SPHINX - steal burgers
VAR TALK - ./textparser.sh "steal 1 burgers" 6145557238 "playerID#int#17|"
TXT PARSE - You successfully stole 1 burger
This information is useful in debugging to see if everything is working correctly.
Back To Top
The grammar files follow JSGF (Java Speech Grammar Format) standards
http://java.sun.com/products/java-media/speech/forDevelopers/JSGF/JSGF.html
- EXAMPLE GRAMMAR FILE
_________________________________________________________
#JSGF V1.0;
/**
* JSGF Digits Grammar for unexceptional.net example
*/
grammar digits;
public <actions> = <actionQUIT> | <actionBurgers>;
<actionQUIT> = quit;
<actionBurgers> = ( Get | Drop | Eat ) Burgers;
_________________________________________________________
* the syntax of JSGF is similar to BNF
* grammar digits uniquely identifies the grammar name and is used
when Sphinx launches. This name is defined in the config.xml that is
part of Sphinx (/home/pxb_utils/sphinx/config.xml)
* the public <X> defines where Sphinx starts when interpreting the grammar
Back To Top
Wav files are used by sphinx to determine what the player says. Sphinx
requires the wav files to be in 16k format in order to properly interpret
them. However since cellphones play/record in 8k format, an application
called "SOX" is required to convert it from 8k to 16k.
sox result/result.WAV -s -r 16000 -w -c 1 result/result_converted.wav
* flags are unknown as this was written by Luke
Above is the command line syntax for running SOX on linux. It converts the 8k
wav file recorded from the phone to 16k for sphinx to use. Thus there are 2
wav files:
result<X>.WAV is the raw 8k version
recorded from the phone and
result_converted<X>.wav
is the converted 16k version.
Back To Top
Whenever Sphinx detects a wav file (specifically result_converted<X>.wav
in a designated directory, in this case, the [/home/pxb_utils/agi-bin/result] directory
Sphinx will try to decode the wav file and see what the player says. When
it finishes, it will write the output to the sphinx_output<X>.txt file
This file is used by varuna_talker to speak back to the player what
Sphinx thought he said.
Back To Top
Text parser contains various classes used for taking the text version of what
the player says and modifying the gamestate to reflect the player's actions.
Text Parser is used in varuna_talker.php to perform a set of events
related to what the player says. So when the player says a command
"GET BEER", the Text Parser must determine if the command is valid
and call the correct Action files to add 1 beer to the players inventory.
The textparser is given a command line input ("GET 1 BEER" <phoneNum> <options>). It
parses what the command is and performs the associated action (GET). Each action has
it's own ACTION<X>.java file which defines what happens when this action is called.
Actions are created using the talk_quest_mngr. However, the logic behind the action
must be defined by the individual developer. These actions affect the gamestate by
modifying the players inventory, stats, etc.
Back To Top
DB Adapter is a semi port of dbFunctions.php, and is used to connect Java and MySQL together.
DB Adapter contains some generic functions to do updates,deletes, as well as selects on
SQL statements. This is primarily used by the various Action<X>.java files to
manipulate the database and game state. It is also used by Varuna.java when trying to
gather player information.
Back To Top
Action<X>.java are generated whenever developers create new actions
in the Talk Quest Manager Content Creation Tool. These action files follow
the default template and do not contain any code that corresponds to the type
of action the name represents.
Whenever an action is created in the Talk Quest Manager, a compile flag is set
so that the next time Varuna Talker is launched, it will automatically compile
all files where the Action<X>.java is located. This prevents errors from
players trying to use a new action before its defined.
It is up to the developer to define the code inside the newly created action files.
Back To Top
Asterisk / Varuna is the telephony system that makes calls out to players whenever a
call file is generated.
Currently, the backend voip service for Asterisk / Varuna is unstable, so Asterisk / Varuna
is restarted everyday.
Asterisk / Varuna is installed on a linux machine. Depending on the setup, it may require
additional hardware (although VOIP doesn't). For more information about setting up and installing
Asterisk, see the Luke's documentation and the links below.
Asterisk Wiki -
http://www.voip-info.org/wiki/view/Asterisk
Asterisk Installation -
http://www.voip-info.org/wiki/index.php?page=Asterisk+installation+tips
Step by Step Instructions -
http://www.voip-info.org/wiki/view/Asterisk+Step-by-step+Installation
After Installation and making sure everything works, it is time to configure your extensions.conf file
so that calls into the Asterisk / Varuna and calls out of Asterisk / Varuna are properly redirected
to the correct
[context,extension,priority] (see Extensions section for more info).
It is important to configure the
[from-internal] section in the extensions.conf file
so that it reflects what you want to happen whenever you call into the Asterisk / Varuna system.
Running Asterisk [straight from asterisk_start.sh]
cd /usr/sbin/
safe_asterisk
# Asterisk -vvv(verbosity)c # interactive console mode (only one can exist)
# Asterisk -vvv(verbosity)r # to connect remotely (more than one can exist)
# when the start script runs it checks for the PID in /var/run, if not there
# it will start a new one. Asterisk itself is relatively robust so don't be
# nervous about restaring. Try to rely on safe_asterisk and killall as the
# zombies are of little consequence apart from being slight memory users.
Stopping Asterisk [straight from asterisk_stop.sh]
/etc/rc.d/init.d/asterisk stop
Launching the Asterisk Prompt Screen [straight from asterisk_prompt.sh]
cd /etc/asterisk/
asterisk -r
Important notes to remember:
Every time you make a modification to the extensions.conf file, you need to launch the
asterisk prompt and run
extensions reload for the changes to take effect
In the event that you get a message along the lines of
"Asterisk is busy and cannot take your call...", many times it is Asterisk
/ Varuna having issues and requiring restart. In this case, simply stop Asterisk / Varuna, wait
several minutes, then restart the process, and it should run normally.
The command
noop(<String>) for extensions.conf is useful for debugging
when setting up the extensions. Using this command, any <String> you pass to noop() will be
outputted to the asterisk prompt screen.
For whatever scripts you set to run, be aware that regardless of whether someone answers the phone or not,
Asterisk / Varuna will still launch the script, however some of it may be cut off depending on the length
of the person's voicemail greeting. This problem is fixed with the use of MachineDetect.
Be sure to read Asterisk AGI -
http://www.voip-info.org/tiki-index.php?page=Asterisk+AGI
which helps if you want to setup different programming languages to run with asterisk (i.e. java,c,php,etc).
Back To Top
The Extensions file in Asterisk/Varuna is the logic behind how calls are directed.
Each extension block inside the extensions.conf file contains a
context, extension, priority, action. This is so that when a callfile is generated,
it targets a context,extension, and priority and performs the action.
The syntax of extensions.conf file is quite simple: Each action is given a priority,
and after that action executes, it will move to the next action with a priority one larger
than itself. There are also ways to branch out of or jump to other extensions without
going consecutively in order. It is similar to assembly programming.
Example Extension:
[numberActivation]
exten => numberActivation,1,Answer
exten => numberActivation,2,Wait(1)
exten => numberActivation,3,AGI,activation_talker.php
exten => numberActivation,4,Hangup()
Syntax of an extension block and example
| Syntax |
|
Example |
[[context]]
exten => [extension],[priority],[action]
|
|
[numberActivation]
exten => numberActivation,1,Answer
|
Definitions of all keywords used in an extension block
| Keyword |
Example |
Explanation
|
| [[context]] |
[numberActivation] |
This is the context of an extension block. Since the context must be
wrapped in [ ], that is why there are 2 [[ ]] around the word [context]
|
| [extension] |
numberActivation |
name of extension to register to context. Note this does
not have to be the same name as the context, you can easily
name the extension 'start' and it would be legal
|
| [priority] |
1 |
the priority to give this action, it must start from 1 and
increase in value and not have duplicate values
|
| [action] |
Answer |
This is the action to perform whenever this priority needs to be executed.
In this case it is to answer the incoming line. Other actions listed above
include waiting 1 second, excuting an AGI script to launch the php file.
and hanging up the call.
|
| [exten =>] |
exten => |
This is syntax to register an action to an extension. Each action you
wish to register must start with exten =>
|
For more complicated examples see the actual extensions.conf file or the
Asterisk Wiki
Back To Top
Call files are generated whenever a call is placed to Asterisk / Varuna.
In terms of Talk Quest, whenever a player enters a hotspot, a call is
generated for that player. This call file contains the basic information
to delect who the player is, and how to interpret the call.
Structure of a call file - <mobileNumber> is the acutal number you are trying to contact
Channel: SIP/<mobileNumber>@sip.broadvoice.com
Callerid: <mobileNumber>
MaxRetries: 1
RetryTime: 10
WaitTime: 30
Context: machine
Extension: machine
Priority: 1
SetVar: TARGETPARAM=varuna
| Keyword |
Explanation |
| Channel |
this is how the call is made, insert whatever service you are using her |
| Callerid |
by placing the targeted number you are dialing, you can access the information
later in any of your custom scripts, otherwise you have no idea which number
Asterisk / Varuna dialed
|
| MaxRetries |
number of times you want to make the call |
| RetryTime |
how long it waits before trying to call again |
| WaitTime |
how long it waits for someone to pickup |
| Context |
targeted context, as defined in extensions.conf |
| Extension |
targeted extension as defined in extensions.conf |
| Priority |
targeted priority as defined in extensions.conf |
| SetVar |
allows you to set a <variable>=<value> that you can later
access in extensions.conf via
(so for TARGETPARAM=varuna, you access the variable via ${TARGETPARAM}, whose value is set to varuna)
SetVar is an optional field that is not needed, but in our Asterisk / Varuna implementation, it is
used in conjunction with MachineDetect so that when the answering machine picks up the call, Asterisk / Varuna
will not be speaking to an answering machine. Since Asterisk / Varuna requires player input (spoken text to
be decoded by Sphinx), varuna_talker scripts should not run when nobody picks up.
Thus, our normal context,extension for any type of call directs to "machine" which will check if someone
answers the phone. If it does, it then redirects control to a new context,extension as defined by the
TARGETPARAM variable. This way, any type of context,extension will only run
if someone answers the phone.
|
More Information
http://www.voip-info.org/wiki/view/Asterisk+auto-dial+out
Back To Top
http://www.voip-info.org/wiki/
While not actually a library, this wiki is a good source to look up information
regarding asterisk and it's various components / command lines to use inside
the extensions.conf file.
Back To Top
http://www.voip-info.org/wiki/view/Asterisk+cmd+MachineDetect+(addon)
Machine Detect is an addon package to asterisk which detects whether a person
picks up the phone or whether it is forwarded to an answering machine. It is
used in extensions.conf to detect dial status and switch to the proper block
of code depending on if the player was actually present or not.
MachineDetect(<X>,<Y>,<Z>)
<X>,<Y>,<Z> are used to tweak the settings to encompass
different types of answering machines (each machine has it's own delay time
before the answering machine kicks in)
See documentation at www.voip-info.org for more information
Back To Top
The blog is the gateway into the game through the web, where various modding tools
and other modules documented in this file are located.
The Index Page current.php, is what players see whenever they log into the site.
Certain things, like the google maps is set to be hidden at first so that players
aren't overwhelmed with information when they first start out and feel completely lost.
At the top of current.php there are 2 links (new Trades and new Messages). These
help reveal any new trades that you have received from other players, as well as
any system messages you have received. System messages are generated information
for when something happens that might not be obvious to the player. Examples are
when another player steals something from you, a trade failed b/c a player was
missing items, or the fact u need to register a valid phone to receive a phone call.
The dynamically swapping of style sheets uses a javascript method of searching for
all stylesheets in the page until it matches the current stylesheet being used, add
the new stylesheet to be swapped, and remove the old one. The stylesheet must be
added first or else when you remove it, the page refreshes and shows the blog w/o
any styles / colors (links turn default purple/blue).
All stylesheets are loaded at first and then removed to create the effect of preloading
so that the background images load faster when a swap is called.
A new data structure is introduced for optimizing the index page. This data structure
holds all the player information that is displayed in the popup div whenever a player is
clicked (from google map).
playerdata[] = {"username" : "", "tradeableItems" : "", "transactions" : "", "tradeRating" : "", "registered" : "", "lastLogin" : "",
"milesFromYou" : "", "currentPos" : "", "realTimeTracking" : "","lastwaypoints" : "",
"history" : };
The datastructure is self explanatory, it is an associative array where each item in the array is described by
the key:value pair. the "history" index however, contains an array, instead of a string like all the others.
History[0] is a boolean flag representing whether the player has the ability to delete the player's history.
History[1]....History[n] represents all 2 wk history spans that will show their travel history in google map.
Back To Top
The footer is in charge of broadcasting all the XML and Server Encoded XML packets
that are generated when the player views a page. These packets cause visual effects
in the Flash Visualizer, indicating player and database activity.
The footer only sends these broadcast packets when the player is actually logged in.
There are no hits / activity broadcasted for anonymous users.
These broadcasts messages are in XML and the Server Encoded XML is required at
broadcasting for the server to actually use the information and not drop it.
(See Alex's documentation about the specifics)
+ XML for Database Action
<db size="$value" table="$key" action="".strtolower($queryType).""/>
XML|:E|db|:A|size|$value|:A|table|$key|:A|action|".strtolower($queryType)."|:X
shows database: size (num rows), table name, and action (Query,Update,Delete)
+ XML for Player login / logout
<web playerid="$playerID" action="$action" />
XML|:E|web|:A|playerid|$playerID|:A|size|$size|:X
shows player: playerID action(login,logout)
+ XML for Page Hits
<web playerid="$playerID" size="$size" url="$page"/>
XML|:E|web|:A|playerid|$playerID|:A|size|$size|:A|url|$page|:X
shows web: playerID, size of the file, and the url of the page
+ XML for Quest Action
<quest playerid="$playerID" type="$type" chakra="$chakra" questid="$questID"/>
XML|:E|quest|:A|playerid|$playerID|:A|type|$type|:A|chakra|$chakra|:A|questid|$questID|:X"
shows quest: playerID, type(active,completed), which chakra association, and questID
Back To Top
GreyMatter is the blogging utility for creating blogs, as well as editing the
look and feel of the Index Page current.php.
gm-comments.cgi has been modified to prevent blog posts that aren't revealed
from coming up as search results
gm-comments.cgi also replaces {{searchform}} with the actual code in the
template and then does search to replace <?$gmposts?> with the actual
list of posts via regular expression substitution
{{searchform}} Since gm-comments.cgi does not properly parse and execute
php code, the block of php code has been moved out of {{searchform}} template
and place right above the call to {{searchform}} in GreyMatter. This code
currently resides in templates > Main Index Template
the way blog posts are prevented are by searching for all active,available, and
completed quests available to that player. Then a list of all blogposts
associated to that player is generated. Using that list, gm-comments.cgi can
compare and see if the player is allowed to see a certain post
Back To Top
The menutree makes use of cookies so that the open / close state of each of
the collapsable folders remains the same after the browser is closed or reloaded.
A cookie is stored as a strings of 0,1,2 depending on whether the link is a
link, closed folder, or open folder respectively. However, because of the dynamic
generation of the quest data links / folders, the cookie string may no longer map
to the generated folder list. Thus a comparison between the cookie string, and the
default generated string for the menu tree is made. If they do not match in length,
the cookie string is parsed into 3 sections: the start, the middle, and the end.
Both the start and end represent the folders before or after the dynamic quest folders.
These values are pulled from the cookie string. The quest data folders are then copied
from the default generated string. What results is that the open / closed states for
all menus other than the quest data are always preserved. However, for the quest data
folders, only the active / available states are preserved. The completed folder will always
be closed, as will be any nested folders inside the active / available / completed folders.
Back To Top
Call Functions is a library that generates the external call files for Asterisk/Varuna
to dial out to a player.
function create_call_file($playerID,$mobileNumber)
This is used when a player registers an account or changes a number, and a number activation
is required to confirm that number.
function createMessageCallFile($mobileNumber,$message)
Whenever a player uses the callbot, this function is called to create the message
and place a call to that player.
Back To Top
DB Functions is a library that connects PHP to MySQL, providing a list of generic
functions to update/delete/select rows from the database. There are also other
specific functions related to broadcasting information as well as checking player info.
some modifications to dbFunctions including functions for sending broadcast info to
the server and visualizer, and code to check associations (in Talk Quest, for
associations between quests to hotspots, hotspots to items, items to actions).
The function checkAssociations is supposed to make sure there are no duplicated entries for the
associations and delete them whenever
BroadcastInfo makes use of a 2d array data structure to store the number of hits to the
database and the number of rows. Its structure is
[TYPE][TABLE] = VALUE
[TYPE][TABLE] = VALUE
The initial structure of looks like the following:
[QUERY ][]
[UPDATE][]
[DELETE][]
So if the someone was to a query on the player table and it returned 5 rows it would
result in having,
Query: Player - 5 rows
[QUERY ][Player] = 5;
[UPDATE][]
[DELETE][]
an update to player on 1 row would be
Update: Player - 1 row
[QUERY ][Player] = 5;
[UPDATE][Player] = 1;
[DELETE][]
Query: Quests - 15 rows
[QUERY ][Player] = 5;
[Quest ] = 15;
[UPDATE][Player] = 1;
[DELETE][]
Query: Player - 20 rows
[QUERY ][Player] = 25;
[Quest ] = 15;
[UPDATE][Player] = 1;
[DELETE][]
As you can see, for each type of query and table, a row is added to the data structure, but
when if a row exists for the query and table, then the value gets added to the existing one.
This way, you can send the broadcast info in one shot and not have to worry about getting
several XML statements saying the player table was queried X number of times.
Back To Top