/*
@version 3.7.1
@author Jobe Makar, Electrotank, Inc
@description This class is used to for communication between a Flash client and ElectroServer.
For more information or help using ElectroServer, please visit http://www.electro-server.com
*/
class ElectroServer extends XMLSocket {
//@exclude
//Last edit: 1/23/2006
//
//Started: 8/15/03
//
//-----Revision History---------
// 9/18/03 Officially released
// 9/30/03 Added version detection. If class connects to an older ElectroServer 3 version then an error appears
// 10/8/03 Fixed createRoom() auto_join bug. Now behaves properly
// 10/11/03 Fixed chat message bug. A pure number chat message was being converted to a number on reentry
// 10/20/03 Changed the way variables are parsed in received plugin message
// 11/5/03 Fixed a case sensitive issue with room variables
// 11/5/03 Fixed a sendMove/moveReceived issue
// 11/7/03 Added FloodingFilterEnabled support
// 11/12/03 In createGameRoom I added support of either description or Description, case insensitive
// 12/14/03 Added the ability to receive an array of variables in the loggedIn event
// 12/16/03 Added setModeratorLabel(true|false, "[Mod]") -- If someone is a moderator then their label gets "[Mod]" appended
// 1/5/04 Fixed default zone name issue
// 1/19/04 Fixed user variable support issues
// 2/1/04 Added getLoggedInUserCount(). Requests the total number of users logged into the server in all zones
// 2/1/04 Added getServerTime(). Returns the number of miliseconds since 1970.
// 2/12/04 getRoomsInZone('zone name') added. It is there for clients that receive higher loads of bandwidth. It triggers onRoomsInZoneLoaded
// 2/23/04 Fixed a WDDX GetRoomsInZone parsing bug
// 2/26/04 Added a hidden room bug work around to class.
// 5/6/04 Added event for the response of getLoggedInUserCount. It is es.loggedInUserCountUpdated(num_logged_in)
// 5/22/04 Added an event to capture the getServerTime method results. onGetServerTime
// 8/8/04 Fixed a bug that caused the userlist to show incorrect results
// 8/15/04 Added rawMessageReceived()
// 8/28/04 Fixed userVariable client-side data saving bug
// 9/26/2004 Added buddy stuff. es.addBuddy("jobem"), es.removeBuddy("jobem"), es.buddyLoggedIn event, es.buddyLoggedOut event
// 9/26/2004 Added getUserLocation("jobem") es.userLocationLoaded event is fired when loaded. username, zone, and room are passed in as a string
// 9/26/2004 Added getUsersInRoom("zone name", "room name"). es.usersInRoomLoaded event is fired. An array of objects with a username property is returned
// 10/15/2004 Enhanced usersInRoomLoaded event. It now also returns the room and zone names
// 11/10/2004 Fixed a uservariable update bug.
// 11/11/2004 Fixed a createGameRoom bug where updatable was always false.
// 12/15/2004 Added a 4th param to the userListUpdated event, it is a reference to the user object
// 1/13/2005 Added an optional 3rd parameter to the login(name, pass, variables) method, 'variables'. It is an object that can contain name value pairs, captured by the login event handler on the server
// 1/20/2005 Fixed userLocationLoaded bug fixed
// 2/27/2005 Added registerRawHandler
// 2/27/2005 Added sendRaw(raw_msg)
// 4/10/2005 Fixed a bug where a uservariable wasn't being fully deleted
// 5/5/2005 Added userListEnabled=true/false property to the room object at creation time.
// 11/7/2005 Fixed bug where connect() method didn't accept ip and port. connect(ip, port) now works.
// 11/9/2005 Bug fixed. onConnection was not returning 'false' or an error when a socket connection failed.
// 11/22/2005 New feature: es.logout(true/false) If the paramter is true then you are logged out and disconnected. If false, then you are logged out and retain your conneciton.
// 12/18/2005 Rare bug fixed related to WDDX and room creation.
// 1/16/2006 Put all documentation inside of this class
//
//!!! Download ElectroServer class updates from here: http://www.electro-server.com/downloads.aspx
//
//=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+
//Events
public var ignore;
/*
Event fired as a result of the {@link #login} method
@description When use use the {@link #login} method to attempt a login, this event is eventually fired.
Event parameters
success (Boolean) Value is true if the login is a success.
error (String) Value exists if success = false.
@example
See {@link #login} for usage.
*/
public var loggedIn:Function;
/*
Event fired as a result of the {@link #connect} method
@description When you use the {@link #connect} method a connection is attempted with ElectroServer. When the connection has
either succeeded or failed this event is fired.
Event parameters
success (Boolean) Value is true if the connection is a success.
error (String) Value exists if success = false. It contains a reason why the connection failed.
@example
function connectionHandler(success:Boolean, error:String) {
if (success) {
gotoAndStop("Login");
} else {
msg.text = error;
trace(error);
gotoAndStop("Error");
}
}
es.onConnection = connectionHandler;
*/
public var onConnection:Function;
/*
Event fired when you change zones
@description Event fired when you enter a new zone. Simply gives you the name of the zone that you have just entered.
A zone is a collection of rooms much like a room is a collection of users. When in a zone you get
information on the other rooms in your zone. You have no knowledge of any of the other zones.
Event parameters
name The name of the newly joined zone.
@example
function zoneChanged(name:String) {
trace("I just entered this zone: "+name);
}
es.zoneChanged = zoneChanged;
*/
public var zoneChanged:Function;
/*
Event fired when the room list changes
@description Event fired when an update to the zone roomlist is received.
If updateType is "all": This is the initial roomlist received when joining a new zone
(or logging in for the first time).
If updateType is "roomupdated": This is just a change in details for one room, such as its description,
the number of users in that room, etc.
If updateType is "roomcreated": The room was just created.
If updateType is "roomdeleted": A room was jut removed. The 'roomReference' parameter is a string representing
the name of the room just deleted. It is not a reference to the room object since it has been deleted.
Note: The reference to the room list can also be retrieved by using the getRoomList() method.
Event parameters
roomList An array of objects describing the list of rooms. (Array)
updateType "all", "roomupdated", "roomcreated", "roomdeleted" (String)
roomReference Reference to the room objec that was updated. (Object)
@example
The following is code that could be used to update a visual list of rooms
(perhaps in a list box component) as updates come in:
function roomListUpdated(roomList:Array, updateType:String, roomReference:Object) {
if (updateType == "all") {
//The entire list is new
showRooms(roomList);
} else if (updateType == "roomupdated") {
//A room that exists was updated
updateRoomInList(roomReference);
} else if (updateType == "roomcreated") {
//A new room was added
addRoomToList(roomReference);
} else if (updateType == "roomdeleted") {
//A room was removed
removeRoomFromList(roomReference);
}
}
es.roomListUpdated = roomListUpdated;
*/
public var roomListUpdated:Function;
/*
Event fired when the room variables in your room change
@description Event fired when a room variable is created, modified, or removed.
See {@link #createRoomVariable}, {@link #deleteRoomVariable}
Room variables are variables actually stored on the server in your room. They can be created, modified,
or removed. By default, a room variable can be modified and will automatically be removed when the user
that created it leaves the room. However, a room variable can be flagged to be persistent which means
that it will nto delete when the user that creates it leaves the room. Also, a room variable can be
flagged as locked, which means that once locked it can no longer be modified (but can still be deleted).
Event parameters
type "all", "updated", "created", "deleted" (Object)
roomVariables An object containing all of the room variables. (Object)
name String name of the variable updated. (blank if type=="all") (Object)
@example
If you created a chat room where you wanted to put an icon next to users that say they want to chat one-on-one
with someone, then room variables can help there. Someone might create a room variable with their username and
the following code is how it would be handled:
function roomVariablesUpdated(type:String, ob:Object, name:String) {
if (type == "updated" || type == "created") {
flagUserAsWantingToChat(name);
}
}
es.roomVariablesUpdated = roomVariablesUpdated;
In the {@link #createRoomVariable} method documention there is code to show a variable being created showing if a secret door has been unlocked or not. Here is that code again followed by the code that would intercept this variable once created:
To create it:
var ob:Object = new Object();
ob.name = "secretDoorUnlocked";
ob.data = "true";
ob.locked = true;
ob.persistent = true;
es.createRoomVariable(ob);
//To intercept it
function roomVariablesUpdated(type:String, ob:Object, name:String) {
if (type == "updated") {
if (name == "secretDoorUnlocked") {
toggleSecretDoor(ob.secretDoorUnlocked);
}
}
}
es.roomVariablesUpdated = roomVariablesUpdated;
*/
public var roomVariablesUpdated:Function;
/*
Event fired as a result of the {@link #createRoom} or {@link #joinRoom} methods
@description Event fired when a you have been accepted or denied access to a room. When you invoke the {@link #createRoom}
method or the {@link #joinRoom} method you will receive a roomJoined event as a response after the server
processes your request. This event passes in an object with a success = true or false property. If success = false
then this object also contains an error message.
Typical errors are due to invalid room passwords (when trying to join a password protected room),
invalid room name, or room full.
Note: the reference to the room that you are in can also be retrieved by using the {@link #getRoom} method.
Event parameters
results An ojbect containing 'success' boolean of true or false, and an 'error' property if needed (Object)
myRoom A reference to the object describing your room (Object)
@example
function roomJoined(results:Object, myRoom:Object) {
if (results.success) {
//Joined the room
gotoAndStop("Chat");
} else {
//Did not join the room
trace(results.error);
msg.text = results.error;
gotoAndStop("Error");
}
}
es.roomJoined = roomJoined;
*/
public var roomJoined:Function;
/*
Event fired when the list of users in your room updates
@description Event fired when the users in your room changes. When you first join a room you get the full user list and
type is "all". After that you only receive "userjoined" and "userleft" updates.
If type is "all" then the userRefrence parameter is blank. If type is "userjoined" then the userReference
parameter contains a reference to the user object. If type is "userleft" then the userReference parameter
is a string name of the user that left (not a reference to the object as the object has been removed).
See also {@link #getUserList}
Event parameters
userList Array of user objects (Array)
type "all", "userjoined", "userleft" (String)
userReference Name of the user that joined or left (String)
@example
function userListUpdated(userList:Array, type:String, userReference:Object) {
if (type == "all") {
//The entire list is new
buildUserList(userList);
} else if (type == "userjoined") {
//A user joined the room
addUserToList(userReference);
} else if (type == "userleft") {
//A user left the room
removeUserFromList(userReference);
}
}
es.userListUpdated = userListUpdated;
*/
public var userListUpdated:Function;
/*
Event fired when you receive a public or private message
@description This is the most common way to receive chat messages.
Event parameters
type Either "public" or "private" (String)
message The message received (String)
from The name of the user that sent the message (String)
variables An object containing the message variables sent, if any (Object)
@example
function gotMessage(type:String, message:String, from:String) {
if (type == "public") {
chatHistory += from+": "+message;
} else if (tyep == "private") {
showPrivateMessagePopUp(message, from);
}
}
es.messageReceived = gotMessage;
*/
public var messageReceived:Function;
/*
Event fired when you receive a public or private move from another player
@description Users can send each other objects to make game creation much easier. See {@link #sendMove}.
Event parameters
type Either "public" or "private" (Object)
object An object sent to you (Object)
from The name of the user that sent the move (Object)
@example
The following is an example of a move that could be seen in a game where characters can jump and shoot.
function moveReceived(type:String, ob:Object, from:String) {
if (type == "private") {
var action:String = ob.action;
if (action == "shoot") {
var x:Number = ob.x;
var y:Number = ob.y;
var angle:Number = ob.angle;
var speed:Number = ob.speed;
createProjectile(x, y, angle, speed);
} else if (action == "jump") {
makeOpponentJump();
}
}
}
es.moveReceived = moveReceived;
*/
public var moveReceived:Function;
/*
Event fired when the AssignedNumber.value property on the users in your room changes
@description Event fired when the users in your room have been renumbered. By default, when creating a room the Numbered
attribute is 'false', meaning the users in that room are not numbered. However, when Numbered is 'true', the
users in the room are numbered.
Why numbered users can be usefull
When creating multiplayer games that use more than two players it is quite a task to keep track of the order
of users in the game. What happens if someone leaves the game in the middle and it is their turn to move?
Due to Internet latency and the various scenarios by which a person can leave a game it is difficult to guarantee
no problems.
With numbered users you always know the order of the users. If it is number 3's turn to move and then number 3
leaves the room, well then it is still number 3's turn because number 4 just shifted down a position.
Since this is kept on the server there is no chance of synchronization problems.
This concept is not the easiest to understand initially, it may help to view sample FLA files.
Note: the userList is passed in to the event handler. The userList can also be retrieved using the
{@link #getUserList} method.
Note: if you use server-side plugins then you can achieve the same benefits much more easily. The benefits
being a centralized location that knows whose turn it is.
Event parameters
userList Array of user objects. (Array)
@example
function usersRenumbered(userList:Array) {
for (var i:Number = 0; i < userList.length; ++i) {
trace(userList[i].AssignedNumber.value);
}
}
es.usersRenumbered = usersRenumbered;
*/
public var usersRenumbered:Function;
/*
Event fired when the client receives a message sent from a plugin
@description Event fired when Flash receives a message from a plugin.
ElectroServer 3 has the ability to run custom-written plugins created using either Java or ActionScript.
These plugins can send messages to individual users or to a room. When a message is received by a Flash client
from a plugin, the name of the plugin is passed in. Also, an action name is passed in. This can be something
like "CreateMonster". The plugin can also send an unlimited number of variables, which are found in the
variables parameter.
Note: Please read ElectroServer 3 documentation on writing server plugins.
Event parameters
plugin The name of the plugin that sent the message (String)
action Action that the plugin wants you to take (String)
variables Object holding variables sent by the plugin (Object)
@example
What follows is a snippet of code that could be straight out of a real-time RPG controlled by a server-side plugin
function pluginMessageReceived(plugin:String, action:String, variables:Object) {
if (plugin == "RPG_Monster_Generator_Plugin") {
if (action == "Spawn_New_Bad_Guy") {
var badGuyType = variables.badGuyType;
var x:Number = variables.x;
var y:Number = variables.y;
var armor:String = variables.armor;
var speed:Number = variables.speed;
var ferocity:Number = variables.ferocity;
addNewBadGuyToMap(x, y, badGuyType, armor, speed, ferocity);
} else if (action == "Picked_Up_Item") {
var item:String = variables.item;
var worth:Number = variables.worth;
addItemToInventory(item, worth);
}
}
}
es.pluginMessageReceived = pluginMessageReceived;
*/
public var pluginMessageReceived:Function;
/*
Event fired when the number of users in the zone changes
@description Event fired when the number of users in the zone changes. Simply gives you the number of users in your
zone when ever that number is changed.
Event parameters
numUsers Number of users in the zone
@example
function zoneUpdated (numUsers:Number) {
trace("The number of people in my zone is: "+numUsers);
}
es.zoneUpdated = zoneUpdated;
*/
public var zoneUpdated:Function;
/*
Event fired when the configuration file has been loaded as a result of {@link #loadConfiguration}.
@description Event fired when the configuration file has finished loading. The configuration XML file is passed
into the callback function. See the provided admin client for example usage.
Event parameters
ob Object containing the parse configuration file.
@example
es.configurationLoaded = function(ob:Object) {
//config loaded
}
es.loadConfiguration();
*/
public var configurationLoaded:Function;
/*
Event fired when the connection to ElectroServer closes.
@description Event fired when connection to the server is lost. If 'true' then the connection was closed due
to forces out side of the Flash client (like ElectroServer closing it or a broken Internet connection).
If 'false' then the connection closed because the {@link #close} method was invoked. (Boolean)
See also {@link #connect} and {@link #close}.
Event parameters
ServerInitiated Boolean value.
@example
function serverClosed(ServerInitiated:Boolean) {
if (ServerInitiated) {
trace("Connction closed by server");
} else {
trace("Connction closed by Flash");
}
}
es.connectionClosed = serverClosed;
*/
public var connectionClosed:Function;
/*
Event fired when the user variables on a user in your room have changed.
@description This event is fired when a uservariable is created or updated that is associated with a user in your room.
See also {@link #createUserVariable} and {@link #deleteUserVariable}.
Event parameters
user object referencing the user who owns the variable (Object)
type Either "created" or "updated" (String)
name Name of the variable created or updated (String)
@example
es.userVariableUpdated = function(user, type, name) {
trace("----------------");
trace("es.userVariableUpdated called");
trace("user="+user.Name.value);
trace(type)
trace("variable name="+name);
trace("variable value="+user.userVariables[name])
}
*/
public var userVariableUpdated:Function;
/*
Event fired when the rooms in your zone are loaded as a result of the {@link #getRoomsInZone} method.
@description This event is fired when the list of rooms in a zone is loaded. The list of rooms is passed in as the
first parameter (see example for accessing the room names off of those room objects). The second parameter
is the name of the zone.
See also {@link #getRoomsInZone}.
Event parameters
roomList List of rooms (Array)
zone Name of zone (String)
@example
es.getRoomsInZone("Chat Area");
es.onRoomsInZoneLoaded = function(room_list, zone_name) {
//This is fired when the rooms have been loaded
//tracing zone name
trace(zone_name);
for (var i = 0; i < room_list.length;++i) {
var ob = room_list[i];
//tracing room name
trace(ob.Name.value);
}
};
*/
public var onRoomsInZoneLoaded:Function;
/*
Event fired when the number of logged in users is received as a result of {@link #getLoggedInUserCount}.
@description
Event parameters
count The number of users logged into ElectroServer
@example
es.loggedInUserCountUpdated = function(count:Number) {
trace("users connected: "+count);
}
es.getLoggedInUserCount();
*/
public var loggedInUserCountUpdated:Function;
/*
Event fired when the server time is loaded as a result of {@link #getServerTime}.
@description
Event parameters
time The time in miliseconds since 1970 as seen be ElectroServer
@example
es.onGetServerTime = function(time:Number) {
trace("server time: "+time);
}
es.getServerTime();
*/
public var onGetServerTime:Function;
/*
Event fired when a raw message is received from a plugin
@description This is used by advanced users. Server-side plug-ins can be used to send messages of any format to a user.
If the message is not of the typical ElectroServer XML protocol then this event is fired and the raw message
is passed through.
This is mainly used for sending extremely condensed messages for real-time games.
See also {@link #registerRawHandler}.
Event parameters
message Raw message as a string (String)
@example
es.rawMessageReceived = function(message) {
trace(message);
}
*/
public var rawMessageReceived:Function;
/*
Event fired when a buddy in your buddy list logs in
@description
This is fired as a result of one of two events:
1) That buddy just logged into the server
2) That buddy was already logged into the server but you just added him to your buddy list. The server
fires this event so that you are updated to know that the buddy you just added is logged in.
See also {@link #addBuddy} and {@link #removeBuddy}.
Event parameters
username Name of buddy who just logged in (String)
@example
es.buddyLoggedIn = function(name) {
//This is fired when a buddy of yours logs in
trace(name +" just logged in")
};
*/
public var buddyLoggedIn:Function;
/*
Event fired when a buddy in your buddy list logs out
@description This is fired as a result of one of two events:
1) That buddy just logged out of the server
2) That buddy was already logged out of the server but you just added him to your buddy list.
The server fires this event so that you are updated to know that the buddy you just added is not online.
Event parameters
username Name of buddy that just logged out (String)
@example
es.buddyLoggedOut = function(name) {
//this is called when a buddy of yours logs out
trace(name+" just logged out");
};
*/
public var buddyLoggedOut:Function;
/*
Event fired when the location of a user has been loaded as a result of {@link #getUserLocation}
@description This event is fired as a result of {@link #getUserLocation}. It tells you the zone and room that a specific
user is in. See {@link #getUserLocation} for more information.
Event parameters
username Username (String)
zone Zone that the user is in (String)
room Room that the user is in (String)
@example
es.getUserLocation("jobem");
es.userLocationLoaded = function(username, zone, room) {
trace(username+", "+zone+", "+room);
};
*/
public var userLocationLoaded:Function;
/*
Event fired when the usrs in a specific room have been loaded as a result of {@link #getUsersInRoom}
@description As a result of getUsersInRoom this event is fired. An array of user objects with a 'name'
property is passed in. Also, the zone name and room name of the users are passed in.
Note: we are using objects with a 'name' property to leave open the chance to add more useful
properties to this in the future, like userVariables. Currently you cann't load userVariables of a
user who is in another room.
Event parameters
users Array of objects (Array)
zone Name of zone that room is in (String)
room Name of room that users are in (String)
@example
es.getUsersInRoom("Chat Area", "Lobby");
es.usersInRoomLoaded = function(users, zone, room) {
//This is fired when the users in a specific room have been loaded
//array is returned with user objects. They have only 1 property, username
trace(zone)
trace(room)
for (var i = 0; i var ob = users[i];
trace(ob.username);
}
};
*/
public var usersInRoomLoaded:Function;
/*
Event fired when a list of zones are loaded as a result of {@link #getAllZones}
@description This event is fired when the list of all zones on the server is loaded. An array of zone names
is passed in. See also {@link #getAllZones}.
Event parameters
zones List of zone names (Array)
@example
es.getAllZones();
es.allZonesLoaded = function(zones) {
//This is called when all zone names have been loaded
for (var i = 0; i //tracing zone names
trace(zones[i]);
}
};
*/
public var allZonesLoaded:Function;
//@exclude Properties
public var ignore2;
//A pointer to the objec that represents you
public var myUser:Object;
//'true' if you are in a game room
public var inGame:Boolean;
private static var _instance:ElectroServer;
private var MajorVersion:Number = 3;
private var MinorVersion:Number = 2;
private var SubVersion:Number = 0;
private var debug:Boolean = false;
private var showModeratorLabel:Boolean = false;
private var moderatorLabel:String;
private var ip:String;
private var port:Number;
private var ConnectedToServer:Boolean;
private var pendingRoom:String;;
private var joiningRoom:Boolean
private var pendingZone:String;
private var zone:Object;
private var auto_join:Boolean;
//'true' if you are the first on in a game room. (Not used much anymore)
public var isGameMaster:Boolean;
private var configXML:String;
//Your username. Can alos be referenced like this: es.getUser().Name.value
public var username:String;
//Your password
public var password:String;
private var buddyList:Array;
private var nodeNameList:Object = {Users:true, Zones:true, UserVariables:true, RoomVariables:true, Rooms:true, Variables:true, BannedUsers:true, Plugins:true, Moderators:true, Words:true, RootWords:true, Templates:true};
private var isConnected:Boolean = false;
/*
@description This class is a singleton, so the constructor is private. To create a new instance of
this class use the 'getInstance()' method.
*/
private function ElectroServer() {
buddyList = new Array();
zone = new Object();
zone.rooms = new Array();
}
private function ValidateVersion(Major:Number, Minor:Number, Sub:Number) {
var ReturnVal:Boolean = true;
if (MajorVersion>Major || isNaN(Major)) {
ReturnVal = false;
} else if (MinorVersion>Minor && MajorVersion == Major) {
ReturnVal = false;
} else if (SubVersion>Sub && MinorVersion == Minor) {
ReturnVal = false;
}
return ReturnVal;
}
//
private function onClose() {
isConnected = false;
connectionClosed(true);
}
/*
Removes a buddy from your list
@description Removes a user from your buddy list
@param Username to remove
@example var user:String = "jobe";
es.removeBuddy(user);
*/
public function removeBuddy(name:String) {
for (var i = 0; i";
send(action, parameters);
}
/*
Loads a list of users for a specific room in a specific zone
@description Loads a list of users in a specific room and zone. When
loading is comple, the 'usersInRoomLoaded' event is fired
@param The zone that the room is in
@param The room you are interested in
@example
es.usersInRoomLoaded = function(userlist:Array, roomName:String, zoneName:String) {
trace("--user list loaded for zone: "+zoneName+", roomName");
for (var i=0;i
*/
public function getUsersInRoom(zone:String, room:String) {
var action = "GetUsersInRoom";
var parameters = ""+zone+""+room+"";
send(action, parameters);
}
/*
Loads the location of any user on the server
@description Loads the location of a user from the server. When loaded the 'userLocationLoaded' event is fired.
@param The name of the user
@example
es.getUserLocation("jobem");
//Capture the response
es.userLocationLoaded = function(username, zone, room) {
trace(username+", "+zone+", "+room);
};
*/
public function getUserLocation(name:String) {
var action = "GetUserLocation";
var parameters = ""+name+"";
send(action, parameters);
}
/*
Tells ElectroServer which plugin to route raw messages to
@description This is an advanced feature. You call this method and pass in the name of an ElectroServer plugin. Then,
if the client needs to send a custom formatted message to the server it can. All messages whose formats are not
recognnized are forwarded on to the plug-in. Instead of a 500 byte XML message you could send a 20 byte custom string.
This works well for high performance real-time games. See also {@link #sendRaw}.
@param The name of the plugin
@example es.registerRawHandler("ShootemUpPlugin");
*/
public function registerRawHandler(name:String) {
var action = "RegisterRawHandler";
var parameters = ""+name+"";
send(action, parameters);
}
/*
Returns an array of your buddies
@description This method returns the list of your buddies as an array. Each element in the array is an object that has the following properties:
username - name of the buddy
isOnline - Boolean (true for online)
ob.status - String (offline or online)
ob.label - Matches the username. For use with list box component
See also {@link #addBuddy}, {@link #removeBuddy}, {@link #buddyLoggedIn}, {@link #buddyLoggedOut}
@example
var myBuddies:Array = es.getBuddyList();
for (var i=0;i
Alternative usage: Also works with a list box component
myList_lb.dataProvider = es.getBuddyList();
*/
public function getBuddyList():Array {
return buddyList;
}
/*
Adds a buddy to your list
@description ElectroServer supports the idea of "buddies". You can add a buddy to your buddy list.
You are told when ever a buddy logs into the server or logs out of the server with the buddyLoggedIn and buddyLoggedOut events.
The moment you add a buddy to your list you are informed if that buddy is logged in or not.
See also {@link #removeBuddy}, {@link #buddyLoggedIn}, {@link #buddyLoggedOut}, {@link #getBuddyList}
@param Name of user to add
@example es.addBuddy("jobem");
*/
public function addBuddy(name:String) {
var buddyExists:Boolean = false;
for (var i = 0; i";
send(action, parameters);
}
}
/*
Closes the connection with ElectroServer
@description Closes the connection to ElectroServer. As a result the {@link #connectionClosed} event is fired. See also {@link #connectionClosed}.
@example es.close();
*/
public function close() {
super.close();
connectionClosed(false);
}
/*
Loads the time from the server
@description Loads the server time in miliseconds. This absolute number itself is rarely useful. This is usually useful
when trying to syncrhonize the client with logic on the server. When the time is loaded the {@link #onGetServerTime}
event is fired. See also {@link #onGetServerTime}.
@example
es.onGetServerTime = function(time:Number) {
trace("server time: "+time);
}
es.getServerTime();
*/
public function getServerTime() {
var action:String = "GetServerTime";
var parameters:String = "";
send(action, parameters);
}
/*
Loads the number of connect users from the server
@description Loads the total number of users connected to ElectroServer. When load is complete {@link #loggedInUserCountUpdated} is fired.
See also {@link #loggedInUserCountUpdated}.
@example
es.loggedInUserCountUpdated = function(count:Number) {
trace("users connected: "+count);
}
es.getLoggedInUserCount();
*/
public function getLoggedInUserCount() {
var action:String = "GetLoggedInUserCount";
var parameters:String = "";
send(action, parameters);
}
/*
Sets the moderator label to be appended to the front of a the name of all moderators
@description All user objects have a 'label' property. If that user is a moderator its label can look different than other users.
To do that use this method. For instance, a moderator may have a label that looks like this "[mod] Jobe". Over all,
this isn't used very often.
@param A Boolean value. If true then it will show the moderator label.
@param The string to append to the front of a moderator's label
@example es.setModeratorLabel(true, "[mod]");
*/
public function setModeratorLabel(val:Boolean, str:String) {
showModeratorLabel = val;
moderatorLabel = str;
if (str == undefined) {
moderatorLabel = " [Moderator]";
}
}
/*
Returns an instance of the ElectroServer class
@description The ElectroServer class is a singleton. You don't use it like this: var es = new ElectroServer(). You get the instance
of ElectroServer like this: var es = ElectroServer.getInstance();
@example var es:ElectroServer = ElectroServer.getInstance();
*/
public static function getInstance():ElectroServer {
if (_instance == null) {
_instance = new ElectroServer();
}
return _instance;
}
/*
Sets the debug property to true or false. If true it traces all inbound/outbound messages
@description This is used to trace all inbound and outbound messages used to communicate with ElectroServer. By default it is not enabled.
It can be very useful when debugging issues. See also {@link #getDebug}.
@param Boolean value. If true then debugging is enabled.
@example es.setDebug(true);
*/
public function setDebug(val:Boolean) {
debug = val;
}
/*
Returns the debug state, true or false
@description Returns either true or false. You can change the debug state using setDebug(true/false);. See also {@link #setDebug}.
@example var debugVal:Boolean = es.getDebug();
*/
public function getDebug():Boolean {
return debug;
}
/*
Returns the IP address that ElectroServer is using
@description Returns the IP address of ElectroServer
@example var ip:String = es.getIP();
*/
public function getIP():String {
return ip;
}
/*
Returns the port that ElectroServer is using
@description Returns the port that ElectroServer is using
@example var port:Number = es.getPort();
*/
public function getPort():Number {
return port;
}
/*
Sets the IP address to use when connecting to ElectroServer
@description Sets the ip address of ElectroServer. When ElectroServer 3 is started (on a physical
server somewhere or on your local machine) it binds to a specific IP address. You must
specify this IP address and the port in order to connect to ElectroServer.
@param The ip address to connect to.
@example
es.setIP("127.0.0.1");
es.setPort(9875);
es.connect();
*/
public function setIP(tempIP:String) {
ip = tempIP;
}
/*
Sets the port to use when connecting to ElectroServer
@description Sets the port that the class will use to connect to ElectroServer. ElectroServer must be listening on this port
@param The port to use
@example
es.setIP("127.0.0.1");
es.setPort(9875);
es.connect();
*/
public function setPort(tempPort:Number) {
port = tempPort;
}
/*
Deletes a room variable
@description Deletes the room variable with the name passed in, even if it is a locked room variable.
For more information on room variables, see {@link #createRoomVariable} and {@link #getRoomVariables}.
@param The name of the room variable to delete
@example es.deleteRoomVariable("welcomeMessage");
*/
public function deleteRoomVariable(name:String) {
var action:String = "DeleteRoomVariable";
var parameters:String = ""+name+"";
send(action, parameters);
}
/*
Loads the list of rooms in a specific zone
@description Loads a room list for a specific zone. When loaded 'onRoomsInZoneLoaded' is fired. See also {@link #onRoomsInZoneLoaded}.
@param The name of the zone
@example
es.onRoomsInZoneLoaded = function(roomlist:Array, zoneName:String) {
trace("Room list loaded for " +zoneName);
for (var i=0;i
*/
public function getRoomsInZone(tmp_zone:String) {
var action:String = "GetRoomsInZone";
var parameters:String = ""+tmp_zone+"";
send(action, parameters);
}
/*
Changes one of many properties in a room
@description Change attributes of the room that you are currently in. Acceptable 'details' are:
description The value is an object (just like in createRoom and createGame). The properties
of the object are description and attributes. Attributes is another object that can hold any number of
custom variables.
updatable The value is true or false. If true, then the room will receive updates
about the zone. If false then it will receive no updates accept regarding itself.
hidden The value is true or false. If true then the room is not seen by any other room.
If false then the room is seen by other rooms within the zone.
capacity The value is a number. This changes the max capacity fo the room. If the value
is -1 then there is no limit.
password The value is a string or blank. If blank then the room is switched to having no
password. If not blank then the password of the room is changed to the new value.
@param The name of the attribute to change
@param The new value for the attribute that is changing
@example
Makes a room hidden:
es.changeRoomDetail("hidden", true);
Changes the password of your room:
es.changeRoomDetail("password", "myNewPass");
Changes the description object:
var ob:Object = new Object();
ob.attributes = new Object();
ob.description = "A cool room";
ob.attributes.some_useful_variable = "asdf";
es.changeRoomDetails("description", ob);
*/
public function changeRoomDetail(detail:String, value) {
var action:String = "ChangeRoomDetails";
var minorAction:String;
var field:String;
detail = detail.toLowerCase();
var pwordXML:String = "";
if (detail == "description") {
minorAction = "ChangeDescription";
field = "Description";
value.attributes.isGameRoom = true;
var wddxOb = new Wddx();
var descXML = "";
} else if (detail == "updatable") {
minorAction = "ChangeUpdatable";
field = "Updatable";
var descXML:String = value;
} else if (detail == "hidden") {
minorAction = "ChangeVisibility";
field = "Hidden";
var descXML:String = value;
} else if (detail == "capacity") {
minorAction = "ChangeCapacity";
field = "Capacity";
if (value == undefined || value == 0) {
value = -1;
}
var descXML:String = value;
} else if (detail == "password") {
minorAction = "ChangePasswordProtected";
field = "Password";
var descXML:String = value;
var protected:Boolean;
if (value == undefined) {
value = "";
}
if (value.length>=1) {
protected = true;
} else {
protected = false;
}
pwordXML = ""+protected+"";
}
var parameters:String = ""+minorAction+""+pwordXML+"<"+field+">"+descXML+""+field+">";
send(action, parameters);
}
/*
Kicks a user from the server
@description Kicks a user from the server. This is only available to moderator level users. A moderator is specified
by a specific username/password combination found in the configuration.xml file.
@param Name of the user to be kicked
@param Reason for kicking
@example es.kick("jobe", "for being too cool");
*/
public function kick(name:String, reason:String) {
if (reason == undefined) {
reason = "";
}
var action:String = "ModeratorCommand";
var parameters:String = "Kick"+name+""+reason+"";
send(action, parameters);
}
/*
Kicks and bans a user from the server
@description Kicks a user from the server and bans them from logging in again. The 'time' parameter is the length
of time in minutes that a user should be banned from the server. If "-1" then the user is banned until the the
server is restarted.
@param Name of user to be banned
@param Reason for banning
@param The amount of time that the user should be banned in minutes
@example
The following bans someone for 20 minutes.
es.ban("jobem", "You have repeatedly been mean.", 20);
*/
public function ban(name:String, reason:String, expires) {
if (reason == undefined) {
reason = "";
}
if (expires == undefined) {
expires = "-1";
}
var action:String = "ModeratorCommand";
var parameters:String = "Ban"+name+""+reason+""+expires+"";
send(action, parameters);
}
/*
Creates a user variable
@description Creates a variable stored on the server associated with the user that created it. As the user
moves from room to room the variable comes with him. When the user enters a room or when any
uservariable is created, removed, or modified, all users in that room are notified of the change.
See also {@link #deleteUserVariable}, {@link #userVariableUpdated}. Note: There is an example file installed
with ElectroServer called UserVariablesTest.fla that is very helpful.
@param Name of the user variable
@param Value of the variable
@example
To create a user variable on yourself:
es.createUserVariable("myIcon", "happy face");
To trace everyone's user variables:
var userlist:Array = es.getUserList();
for (var i=0;i
*/
public function createUserVariable(name:String, value:String) {
var action:String = "UpdateUserVariable";
var parameters:String = "Create"+name+""+value+"";
send(action, parameters);
}
/*
Loads a list of all the zones currently established
@description Loads the list of zones on the server. When loaded 'allZonesLoaded' event is fired. See also {@link #allZonesLoaded}.
@example
es.allZonesLoaded = function(zones:Array) {
trace("--All Zones--");
for (var i=0;i
*/
public function getAllZones() {
send("GetAllZones", "");
}
/*
Updates a user variable
@description This updates an existing user variable. It works just like creating a user variable. See also {@link #createUserVariable}, {@link #deleteUserVariable}.
@param The name of the variable to update
@param The new value of the variable
@example es.updateUserVariable("myIcon", "sadFace");
*/
public function updateUserVariable(name:String, value:String) {
var action:String = "UpdateUserVariable";
var parameters:String = "Update"+name+""+value+"";
send(action, parameters);
}
/*
Deletes a user variable
@description Deletes an existing user variable. See also {@link #createUserVariable}, {@link #updateUserVariable}.
@param Name of variable to be deleted
@example es.deleteUserVariable("myIcon");
*/
public function deleteUserVariable(name:String) {
var action:String = "UpdateUserVariable";
var parameters:String = "Delete"+name+"";
send(action, parameters);
}
/*
Creates a room variable
@description Creates or updates a variable in the room on the chat server. The variable can
be flagged as locked and/or persistent.
Deeper explanation
ElectroServer supports room variables. This means that a Flash client can create a variable at the room level
that is actually stored in ElectroServer. While ElectroServer is the 'master' of all of these room variables, each Flash
client knows about all of the room variables as well. When ever a room variable is created, modified, or deleted, every
user in that room is notified and the ElectroServer object updates this information internally.
When room variables are created, modified, or deleted an event in the ElectroServer object called {@link #roomVariablesUpdated}
is fired. See that event for more information. The room variables can be accessed at any time by using the {@link #getRoomVariables}
method.
Room variables can be created and then modified. A room variable can be created and locked so that it cannot be modified
any more (but can still be deleted). And a room variable can be flagged as persistent, which means that it is not automatically
deleted when the user that created it leaves the room.
Why room variables are useful
With room variables you have a centralized location to store data. If, for instance, you wanted to
create an avatar chat where chracters could walk around and chat, then room variables can help in the following way:
For each user in the room you can create a room variable that stores his position and the type of character
that he is using. Then when someone new joins the room their Flash client just uses the room variables to determine
where to place the avatar characters. Everytime someone moves their avatar character then they send a room variable
update to update its postion on the server.
Without room variables the way that the above would be accomplished would be by sending information separately
to everyone in the room round-robin style. This is not good practice, causes synchronization issues, and uses more bandwidth.
Here are two good examples of persistent room variables (meaning that they do not delete when the user that created them leaves
the room):
1.) A Flash white board. You can use persistent room variables to store the drawings.
Then as people leave and new people come into the white board they can see everything.
2.) For a multiplayer game you can build something in the world or leave something behind
(like scorch marks form an explosion). When you leave the variable remains and so everyone can see your contribution.
Here is a good example of a locked room variable:
Let's say you wanted to create a scavenger hunt game. This game has several people in it and there are say,
10 objects to collect. You can collect one by moving your character to the object and pushing a special key.
Well, what if two people reach the same object at the same time? How do you know who actually collected it?
There is no way to do this without server-side help, like locked room variables.
If your username is "jobem" and you collect a "gold cup" then you can set a locked user variable into the room called:
goldCup = "jobem"
When everyone receives this room variable update they can flag that object as collected. If someone tries to
collect the object in that 100 or so miliseconds of Internet latency then they will still fail because they will
not be able to create the room variable as it is already locked!
To 'clean up' the game to start over you would then have to delete each of those room variables.
@param An object containing many optional properties. Here are those properties:
name The name of the room variable to be created or updated. (String)
data The value of the room variable to be created or updated. (String)
locked Optional property. If true then the variable can not be modified once created in the room,
however it can still be deleted. The default value is false. (Boolean)
persistent Optional property. If true then the variable remains in the room after the user that
created it leaves the room. If false then the variable is deleted when the user who created it leaves the room.
The default value is false.
@example
The following code creates a room variable on the server in your current room. The variable is not locked and
will be removed when you leave the room:
var ob = new Object();
ob.name = "NumberOfBadGuys";
ob.data = "30";
es.createRoomVariable(ob);
The following code creates a room variable on the server in your current room. This variable is locked, meaning that
it cannot be modifed (only deleted). It is also persistent, which means it will not die if you leave the room:
var ob:Object = new Object();
ob.name = "secretDoorUnlocked";
ob.data = "true";//this is a string because all room variables are strings
ob.locked = true;
ob.persistent = true;
es.createRoomVariable(ob);
*/
public function createRoomVariable(ob:Object) {
var name:String = ob.name;
var data = ob.data;
var persistent:Boolean = ob.persistent;
var locked:Boolean = ob.locked;
if (persistent == undefined) {
persistent = false;
}
if (locked == undefined) {
locked = false;
}
if (zone.myRoom.roomVariables[name] == undefined) {
var action:String = "CreateRoomVariable";
var parameters:String = ""+name+"";
} else {
var action:String = "UpdateRoomVariable";
var parameters:String = ""+name+"";
}
send(action, parameters);
}
/*
Returns a reference to the zone that you're in
@description Returns an object representing your current zone. This object has the following properties:
numUsers - This is number of people in your zone.
name - This is the name of the zone that you are in.
@example
var myZone:Object = es.getZone();
trace(myZone.name);
trace(myZone.numUsers);
@returns An object representing the zone that you are in.
*/
public function getZone() {
return zone;
}
/*
Sends an object to the room or to an array of specific users
@description Sends an object to the room or to an array of specific users. Using the sendMove method you
actually send an ActionScript object to the room or to specific users. The object is serialized
using the WDDX protocol, sent to the user, deserialized, and used.
When the user receives the object the {@link #moveReceived} event is fired.
Note: The WDDX serialization ActionScript classes are used courtesy of Branden Hall.
@param Should be the string "all" or an array of user names. (String or Array)
@param An ActionScript object to send to the other users (Object)
@example Here is a simple example of how to send a chess move to another user.
var ob:Object = new Object();
ob.action = "move_piece";
ob.piece = "white_queen";
ob.y_tile = 7;
ob.x_tile = 6;
es.sendMove("all", ob);
Here is an example of how you could send an array to everyone in your room.
var ob:Object = new Object();
ob.action = "ListOfFriends";
ob.friends = new Array ("Jobe", "Mike", "Robert", "Kelly");
es.sendMove("all", ob);
What follows is an example of a private game move that is send to only 2 other people. Let's say they are on
your team in the game. You are giving them some ammo.
var ob:Object = new Object();
ob.action = "GiveAmmo";
ob.ammoType = "Uzi";
es.sendMove(["mike", "robert"], ob);
*/
public function sendMove(who, ob:Object) {
var wddxOb:Wddx = new Wddx();
var moveXML:XML = wddxOb.serialize(ob);
if (who.toLowerCase() == "all") {
var action:String = "SendPublicMessage";
var parameters:String = "ActionMoveMoveTypePublic";
} else {
var action:String = "SendPrivateMessage";
var users:Array = who;
var usersXML:String = "";
for (var i = 0; i"+user+"";
}
usersXML += "";
var parameters:String = usersXML+"ActionMoveMoveTypePublic";
}
send(action, parameters);
}
/*
Sends a message to a plugin
@description Sends a request to a custom-written plugin in ElectroServer. You must specify the name
of the plugin and the method to be executed. The plugin accepts this information and returns
a result if necessary.
ElectroServer 3.0 has the ability to accept plugins. Plugins can be written in Java or ActionScript.
With ElectroServer plugins you can easily extend the functionality of ElectroServer and create applications
such as multiplayer real-time games! Plugins are super powerful and super cool. Check out http://www.electro-server.com
for more information on them.
@param Name of the plugin that you are trying to communicate with. This is specified in the configuration.xml file.
@param This is a string that the plugin will use to determine what to do with your request.
@param This is an optional parameter, an object of name value pairs. All values should be strings.
@example
The following could work with a plugin written to store white board data. The white board could then
inform all new users to the room of the current state of the board. This code could tell the plugin to
draw a line. It is then up to the plugin to send this information to the other people in the room.
var parameters:Object = new Object();
parameters.startx = 200;
parameters.endx = 300;
parameters.starty = 37;
parameters.endy = 110;
parameters.color = "blue";
es.pluginRequest("WhiteBoardScriptPlugin", "DrawLine", parameters);
*/
public function pluginRequest(plugin:String, method:String, parameters:Object) {
var action:String = "ExecutePlugin";
var variableXML:String = "";
if (parameters != undefined) {
variableXML = "";
for (var i in parameters) {
variableXML += ""+i+""+parameters[i]+"";
}
variableXML += "";
}
var params:String = ""+plugin+""+method+""+variableXML;
send(action, params);
}
/*
Returns an object full of variables
@description Returns an object whose properties are ElectroServer room variables. Each property of this object
is a variable stored at the room level actually on the server. These properties can be accessed either directly
(like object.myVariable) or by using a 'for...in' loop. See the example.
See also {@link #createRoomVariable}, {@link #deleteRoomVariable}
@example
To simply show all of the room variables for a room in the output window, use the following code:
function showRoomVariables() {
var roomVariables:Object = es.getRoomVariables();
for (var i in roomVariables) {
trace(i+"="+roomVariables[i]);
}
}
Or you can access a room variable directly like the following:
var musicLoop:String = es.getRoomVariables().musicLoop;
@returns An object. Each property in the object is a variable for that room.
*/
public function getRoomVariables() {
return zone.myRoom.roomVariables;
}
/*
Returns an array of rooms
@description Returns the list of rooms in your zone as an array. Each element in the array in an
object describing a room. From each element you gain information about a room such as its name,
description, number of users, maximum number of users allowed, and if the room is password protected.
Note: A zone is a collection of rooms much like a room is a collection of users.
Properties of each room object returned in the array
Each element in the room list array is an object describing a room. Here are the properties of a room object:
Name.value The name of the room
Description.value The room description if there is one.
attributes (an object containing the following room properties):
attributes.users The number of users in the room
attributes.MaxCapacity The maximum number of users allowed in this room. '-1' means there is no limit.
attributes.IsPasswordProtected A boolean value specifying if the room requires a password to enter.
attributes.Users The number of people in that room.
See also {@link #createRoomVariable}, {@link #deleteRoomVariable}.
@example
The code that follows is a simple way to just display the rooms in your current zone in an HTML enabled
text filed. Note: this does not make use of the the other properties of the room objects.
function showRooms() {
var roomListBoxStr:String = "";
var roomlist:Array = es.getRoomList();
for (var i = 0; i";
}
roomListBox.htmlText = roomListBoxStr;
}
@returns An array. Each element in the array is an object.
*/
public function getRoomList() {
return zone.rooms;
}
/*
Returns a reference to the room you're in
@description Returns the room object that describes your room. This object contains information about your
room such as it's name, number of users in it, if it is password protected, its maximum capacity,
and all of the room variables. For more information about the properties on the room object see {@link #getRoomList}.
@example var myRoomName:String = es.getRoom().Name.value
@returns Object that describes the room that you are in.
*/
public function getRoom() {
return zone.myRoom;
}
/*
Returns an array of users
@description Returns an array of objects each of which describes a user in your room. The properties of
each object are 'Name.value' which is a string, and 'moderator' which is a boolean value. If 'moderator'
is true then that user is a moderator. There is also a property called 'userVariables'.
User variables are variables saved on the server and associated with a specific user. This is useful
for carrying information about a user around from room to room. See {@link #createUserVariable} for more
information on user variables.
See also {@link #getUser}.
@example This gets the user list, loops through it, and traces out the names of the users.
var list:Array = es.getUserList();
for (var i=0;i
@returns An array of objects. Each object describes a user in your room.
*/
public function getUserList() {
return zone.users;
}
/*
Creates a room with specific flags
@description Creates a room for a game. This method accepts an object with exactly the same properties
as the {@link #createRoom} method does. Please see that method for full details.
The flag that shows that this room is a game room is found in the room
object as: roomOb.description.attributes.isGameRoom, and has a value of 'true'.
Note: The createGameRoom method differs from the creatRoom method only because it flags the
room as being a game room. When the room is created, modified, or removed, the same events are
fired as with a regular room. By flagging a room as a game room it is easier to show a difference
in the room list.
Note: This method is not used very frequently. Developers, in general, prefer to just use {@link #createRoom}.
@param Object describing room to be created
@example
var roomOb:Object = new Object();
roomOb.zone = "Game Zone";
roomOb.roomName = "DiePleez";
es.createGameRoom(roomOb);
*/
public function createGameRoom(roomOb:Object) {
if (roomOb.attributes == undefined) {
roomOb.attributes = new Object();
}
roomOb.attributes.isGameRoom = true;
if (roomOb.updatable != true) {
roomOb.updatable = false;
}
roomOb.numbered = true;
createRoom(roomOb);
inGame = true;
}
/*
Joins you to a game room
@description A game exists in a room. To join that game you must join that room. This method handles that for you.
If you pass in a playerType of "player" then you are joining that game to become a player.
If you pass in a playerType of "spectator" then you are just there to watch.
@param The name of the room
@param The password for the room, if any.
@param Either "player" or "spectator" depending on why you're joining the game.
@param The name of the zone if it differs from the one you're currently in.
@example es.joinGame("Mini Golf 173", "", "player");
*/
public function joinGame(room:String, password:String, type:String, zone:String) {
type = type.toLowerCase();
if (type == "player" || type == undefined) {
var numbered:Boolean = true;
} else if (type == "spectator") {
var numbered:Boolean = false;
}
joinRoom(room, password, zone, numbered);
inGame = true;
}
/*
Special login for admin users
@description This method is exactly the same as the {@link #login} method except that it informs the server
that this user is trying to login as an administrator. There is only 1 administrator per
instance of ElectroServer. The administrator's username and password are set in the configuration.xml file.
Administrators, once logged in, have a greater level of access than do users or moderators.
@param Username of admin
@param Password of admin
@example es.adminLogin("system", "electroserver");
*/
public function adminLogin(tempUsername:String, tempPassword:String) {
myUser.username = tempUsername;
if (tempPassword == undefined) {
tempPassword = "";
}
myUser.password = tempPassword;
username = myUser.username;
password = myUser.password;
var action:String = "AdminLogin";
var parameters:String = ""+myUser.username+""+myUser.password+"";
send(action, parameters);
}
/*
Loads configuration file if logged in as an admin
@description Loads the configuration file for the server (only a logged-in admin can do this). Once the configuration
file is loaded the {@link #configurationLoaded} event is fired.
The configuration file contains all of the configurable information for ElectroServer 3. It is used
by admins to configure the server. They can modify many things such as the language filter, plug-ins,
and banned users.
Admin functionality is not fully documented as it is expected that you will use the provided admin client.
@example
es.configurationLoaded = function(ob:Object) {
//config loaded
}
es.loadConfiguration();
*/
public function loadConfiguration() {
var action:String = "LoadConfiguration";
var parameters:String = "";
send(action, parameters);
}
private function parseConfig(config:String) {
XML.prototype.ignoreWhite = true;
var temp:XML = new XML(config);
var params:Object = new Object();
parseParameters(temp.firstChild.childNodes, params);
configurationLoaded(params);
}
/*
Sends a public or private message to the room or to an array of specific users
@description Send a message to the room or an array of specific users. With this method a message can be
sent to a room (public message) or to a list of users (private message). You can send an unlimited
list of variables along with any message (see example).
When a message is sent it goes to ElectroServer where it is then broadcast to the appropriate people
(the room or private users). When the message is received by these users the {@link #messageReceived} event is
fired. See the {@link #messageReceived} event for more information.
Note: The variables parameter to this method is optional.
Note: Private messages can be sent to a user anywhere on the server. Each user has a unique
username (you can't have two "john" users at the same time). So when you send a private
message to "john" it will find him in any room in any zone.
@param To send to the room this should be "public" or "all". To send to an array of users it should be "private".
@param The string message to send.
@param The array of users to send to. Each element should be a username.
@param An object of name value pairs. Each value should be a string.
@example
Here is the most simple example of sending a message to a room:
var message:String = "Hello world!";
es.sendMessage("public", message);
Here is a simple of example of how to send a message to a room with variables:
var message:String = "Hello world!";
var variables:Object = new Object();
variables.textColor = "yellow";
variables.soundToPlay = "boink";
es.sendMessage("public", message, variables)
Here is a simple example of how to send a private message to three people with variables:
var message:String = "Hello world!";
var variables:Object = new Object();
variables.textColor = "yellow";
variables.soundToPlay = "boink";
var users:Array = new Array();
users.push("Kelly");
users.push("Robert");
users.push("Mike");
es.sendMessage("private", message, users, variables);
*/
public function sendMessage(type:String, message:String, users, variables:Object) {
var type:String = type.toLowerCase();
if (type == "public" || type == "all") {
//'users' is actually the variables for public messages
sendPublicMessage(message, users);
} else if (type == "private") {
sendPrivateMessage(message, users, variables);
}
}
/*
Joins you to a room
@description Joins you to a room in a specified zone. You can only join a room that has already been created.
If a room has not yet been created then you must first create it using the
createRoom method, and then ElectroServer will automatically join you to that room. See also {@link #roomJoined}.
The password parameter can be left blank or can be "" if no password is needed. The 'zone' parameter can
be left blank if you are already in a zone and the room that you are joining is in the same zone. However,
if you have just logged in to the server and have not yet joined a room, then the zone must be specified.
More detail for beginners
A room is a collection of users. In a room you can see other users in your room. When in a room you cannot
see users in any other rooms (you only know that they other rooms exist and you know how many people are in them).
In a room you can send messages which are received by other people in that room.
Much like a room is a collection of users, a zone is a collection of rooms. In a zone you can see all of the rooms
in that zone, but you have no information if any other zones exist or any information about other zones.
@param Name of the room to join
@param Password for the room, if any (optional)
@param The name of the zone that the room is in. Only needed if it is in a different zone then you are currently in. (Optional)
@param Either 'true' or 'false'. If 'true', then you are given a number in the room. This can be useful in some games. (Optional)
@example es.joinRoom("Lobby", "", "Chat Area");
or,
es.joinRoom("SecretRoom", "secret_password", "Chat Area");
or if you are already in a zone and want to join another room in that zone with no password, then it can be condensed to this:
es.joinRoom("Game talk");
*/
public function joinRoom(room:String, password:String, zoneName:String, numbered:Boolean) {
var action = "JoinRoom";
if (numbered == undefined) {
numbered = true;
}
if (password == undefined) {
password = "";
}
if (zoneName == undefined) {
zoneName = getZone().name;
if (zoneName == undefined) {
zoneName = "Chat Area";
}
}
pendingZone = zoneName;
pendingRoom = room;
inGame = false;
var parameters:String = ""+zoneName+""+room+""+password+""+numbered+"";
send(action, parameters);
}
/*
Creates a room
@description Creates a room in a specific zone and then joins you to that room. See below for description
of each of the configurable properties of a room.
Note: If you attempt to create a room that already exists then internally the ElectroServer class will
receive an error and you will automatically be joined to that room (since it exists). If that is not behavior
that you want in your application, then set the 2nd parameter in createRoom to false.
Properties of the room object
The roomOb object can contain many properties to customize the room. Some of them are required while others are not.
password If blank the room is not password protected. If it contains anything then the room is password protected.
userVariablesEnabled If blank or 'false' then user variables are not enabled for this room (increases performance).
If 'true', then user variables are enabled for the room. See createUserVariable, login, or userVariableUpdated for
more information.
hidden If blank or 'false' then the room is not hidden. If 'true', then the room is hidden and cannot be seen
by the other rooms in your zone. This is often used for game rooms.
zone This is the zone in which you want to create a room. If the zone does not yet exist then it will be
created. Required.
roomName The name of the room to be created. Required.
numbered If blank or 'false' the room does not number its users. If 'true' then it does. See the
{@link #usersRenumbered} event.
capacity If blank or -1 then the room has no maximum size. If the number is greater than 0 then the
room created can only grow to a certain user size.
description Can be left blank or be a string describing the room.
updatable If blank or 'true' then the room is updatable. If 'false' then it is not. A room that is
updatable receives zone updates and roomList updates. If it is not updatable then it only receives updates
regarding itself (userListUpdates, etc). This increases performance for that room, recommended for games.
FloodingFilterEnabled If blank it is set to false, which means it's not enabled. When enabled the room checks
to see if users send messages too quickly to the server. This is called flooding. If flooding is detected then the
user is kicked. Flooding properties can be configured in the configuration.xml file.
userListEnabled The default is true. When enabled, the users in a room are informed of the list of users
in that the room. Also the room receives {@link #userListUpdated} events when users join or leave. If set to
false, then ElectroServer sends no information or updates about the users in a room. This can be useful to set to
false in rooms that have many users to cut down on message traffic.
roomVariables Can be left blank if you don't want to create a room with room variables. This is an array
of objects, each of which describes a room variable. The properties of a room variable are 'name'
(name of variable), 'data' (value of variable), 'persistent' (optional Boolean), 'locked' (optional Boolean).
Room variables can be created using the {@link #createRoomVariable} method. See that method for more details.
attributes Optional property. This is an object that can contain variables or arrays. It is attached
to the room much like the room description is. This means that it is accessible by people in other rooms.
plugins Optional property. ElectroServer 3 supports the ability to use server-side plugins. You can access
custom-written ActionScript or Java plugins from Flash on the server. But in order to access them they must be
instantiated when creating a room. This property is an array of objects. Each object represents a plugin that you
want to instantiate for the room. The 'name' variable on that object is the name of the plugin. The object can
contain another object called 'variables' if you want to pass variables into the plugin. Using plugins is an
advanced feature that requires a moderate level of understanding of ElectroServer and the ElectroServer object.
@param An object representing the room to be created
@param Boolean value, default is true. If true and the room that you are creating already exists, then you'll be joined to that room.
@example
Here is the most basic way to create a room:
var roomOb:Object = new Object();
roomOb.zone = "Chat Area";
roomOb.roomName = "Lobby";
es.createRoom(roomOb);
Here is a long-winded example of creating a room with all properties used except plug-ins:
var roomOb:Object = new Object();
roomOb.zone = "Chat Area";
roomOb.roomName = "Lobby";
roomOb.hidden = false;
roomOb.numbered = false;
roomOb.userVariablesEnabled = false;
roomOb.description = "You can chat all day long in this room!";
roomOb.password = "";
roomOb.capacity = -1;
roomOb.updatable = true;
//room vars
roomOb.roomVariables = new Array();
var ob:Object = new Object();
ob.name = "BackgroundMusic";
ob.data = "AmbientSounds";
roomOb.roomVariables.push(ob);
//end room vars
es.createRoom(roomOb);
Here is an example creating a room with two plugins:
var roomOb:Object = new Object();
roomOb.zone = "Chat Area";
roomOb.roomName = "Lobby";
roomOb.plugins = new Array();
roomOb.plugins.push({name:"ShootEmUpPlugin"});
roomOb.plugins.push({name:"ScoreSaverPlugin"});
es.createRoom(roomOb);
*/
public function createRoom(roomOb:Object, auto:Boolean) {
//roomOb properties: zone, roomName, hidden, numbered, UserVariablesEnabled, Description
//Password, Capacity, roomVariables
if (auto == undefined || auto == "true") {
auto = true;
} else {
auto = false;
}
auto_join = auto;
var action:String = "CreateRoom";
var password:String = roomOb.password;
var UserVariablesEnabled:Boolean = roomOb.userVariablesEnabled;
var hidden:Boolean = roomOb.hidden;
var zoneName:String = roomOb.zone;
var roomName:String = roomOb.roomName;
var numbered:Boolean = roomOb.numbered;
var capacity:Number = roomOb.capacity;
var description:String = roomOb.description;
var roomVariables:Array = roomOb.roomVariables;
var updatable:Boolean = roomOb.updatable;
var plugins:Array = roomOb.plugins;
var FloodingFilterEnabled:Boolean = roomOb.FloodingFilterEnabled;
var userListEnabled:Boolean = roomOb.userListEnabled;
var descOb:Object = new Object();
if (userListEnabled == undefined) {
userListEnabled = true;
}
if (description == undefined) {
description = roomOb.Description;
if (description == undefined) {
description = "";
}
}
if (FloodingFilterEnabled == undefined) {
FloodingFilterEnabled = false;
}
descOb.description = description;
if (roomOb.attributes != undefined) {
descOb.attributes = roomOb.attributes;
}
var wddxOb:Wddx = new Wddx();
var descXML:XML = wddxOb.serialize(descOb);
if (zoneName == undefined) {
zoneName = getZone().name;
if (zoneName == undefined) {
zoneName = "Chat Area";
}
}
if (updatable == undefined) {
updatable = true;
}
if (hidden == undefined) {
hidden = false;
}
if (capacity == undefined) {
capacity = -1;
}
if (numbered == undefined) {
numbered = false;
}
if (password == undefined) {
password = "";
}
if (UserVariablesEnabled == undefined) {
UserVariablesEnabled = false;
}
if (roomVariables == undefined) {
var roomVariableXML:String = "";
} else {
var roomVariableXML:String = "";
for (var i = 0; i";
str += ""+name+"";
str += "";
str += "";
roomVariableXML += str;
}
roomVariableXML += "";
}
if (plugins == undefined) {
var pluginXML:String = "";
} else {
var pluginXML:String = "";
for (var i = 0; i"+j+""+pluginVarValue+"";
}
pluginVariablesXML += "";
}
pluginXML += ""+name+""+pluginVariablesXML+"";
}
pluginXML += "";
}
var parameters:String = ""+zoneName+""+roomName+""+password+""+capacity+""+roomVariableXML+pluginXML+"";
joiningRoom = true;
pendingRoom = roomName;
pendingZone = zoneName;
inGame = false;
send(action, parameters);
}
private function sendPublicMessage(message:String, variables:Object) {
var action:String = "SendPublicMessage";
//var parameters = "Test VarYaya";
var variableXML:String = "";
for (var i in variables) {
var value:String = variables[i].toString();
variableXML += ""+i+"";
}
if (variableXML != "") {
variableXML = ""+variableXML+"";
} else {
variableXML = "";
}
var parameters:String = ""+variableXML;
send(action, parameters);
}
private function sendPrivateMessage(message:String, users:Array, variables:Object) {
var action:String = "SendPrivateMessage";
var usersXML:String = "";
for (var i = 0; i"+user+"";
}
usersXML += "";
var variableXML:String = "";
for (var i in variables) {
var value = variables[i];
variableXML += ""+i+"";
}
if (variableXML != "") {
variableXML = ""+variableXML+"";
} else {
variableXML = "";
}
var parameters:String = usersXML+""+message+""+variableXML;
send(action, parameters);
}
private function connectionResponse(success:Boolean) {
//This occurs when the basic connection is established with the socket-server
ConnectedToServer = success;
if (!ConnectedToServer) {
//Could not find server or server is turned off
connectionEstablished(false, "Could not establish a server connection");
}
}
private function connectionEstablished(success:Boolean, reason:String) {
//Sucessfully connection to ElectroServer is a two stage process.
//First you must establish a connection. Then ElectroServer must tell you that it is ok.
if (success && ConnectedToServer) {
//connected successfully
isConnected = true;
onConnection(true);
} else {
//Did not connect successfully
onConnection(false, reason);
}
}
private function XMLReceived(info:XML) {
var validXML:Boolean = info.toString().substr(0, 1) == "<";
if (validXML) {
parseXML(info);
} else {
rawMessageReceived(info.toString());
}
}
private function parseXML(data:XML) {
//hidden
//Every packet of XML that is pushed in from the server hits this method forist
if (getDebug()) {
trace("-----incomming----");
trace(data);
}
var info:Array = data.firstChild.childNodes;
//Every XML packet has an action
var action:String = info[0].firstChild.nodeValue;
//Parse the parameters into easy-to-use data objects
var parameters:Array = info[1].childNodes;
var params:Object = new Object();
parseParameters(parameters, params);
//Apply the action
applyAction(action, params, data);
}
private function isArrayNodeName(nodeName:String):Boolean {
//hidden
//The parseParameters function treats all nodes the same unless they are in
// the 'nodeNameList', in which case they are converted to arrays
//This function returns true|false depending on if the nodeName is in the list
if (nodeNameList[nodeName]) {
return true;
} else {
return false;
}
}
private function terminateHere(xmls:XML):Boolean {
//hidden
//This is used by parseParameters to determine how deep the XML goes
return xmls.childNodes[0].hasChildNodes() ? false : true;
}
private function send(action:String, parameters:String) {
//hidden
var message:String = ""+action+""+parameters+"";
if (getDebug()) {
trace("---out going----");
trace(message);
}
super.send(message);
}
/*
Sends a raw unchanged string to a plugin
@description Used in conjunction with {@link #registerRawHandler}, this advanced method is used to send a raw message
directly to ElectroServer. It won't be re-formatted by the ElectroServer class. It's just sent as-is. ElectroServer
captures it and forwards it to the plugin specified when you used {@link #registerRawHandler}.
@param The raw string to send.
@example
es.sendRaw("t|23|f|90");
*/
public function sendRaw(str:String) {
super.send(str);
}
private function parseParameters(info:Array, parentOb:Object) {
//hidden
//This is a generic recursive method which walks the parameters node of the message
//it parses the XML into generic data objects
//====
// example:
// Success
// parses to parameters.results which is an object, the value of 'Results' is:
// parameters.Results.value
for (var i = 0; ies.logout();
*/
public function logout(disconnect:Boolean) {
if (disconnect == undefined) {
disconnect = true;
}
var action:String = "Logout";
var parameters:String = ""+disconnect+"";
send(action, parameters);
}
/*
Logs you into the server
@description Before you can use any of the server functionality you must login to the server. Using this method is
how that is accomplished. If ElectroServer has not been configured to accept passwords, then the password
field is not required.
The password field is used by the server in one of two ways:
1) To verify that you are a moderator for the server. A moderator has extended abilities such as kick and ban.
2) The password is passed through a custom-written login event handler for the server. This would be in place to verify login
information against a database.
The login method returns nothing. However, once the server has either accepted or denied your login request the
{@link #loggedIn} event is fired.
@param The username to use
@param The password to use. (Optional)
@param An object containing variables to be sent to ElectroServer. This is useful when using a custom server-side login event handler. (Optional)
@example
function loginResponse(success:Boolean, error:String) {
//This function is called when the server responds after a login request is sent
if (success) {
//properly logged in
gotoAndStop("Chat")
} else {
//not properly logged in, there was an error
msg.text = error;
trace(error);
gotoAndStop("Error")
}
}
es.loggedIn = loginResponse;
es.login("jobem");
*/
public function login(tempUsername:String, tempPassword:String, variables:Object) {
username = tempUsername;
if (username == undefined || username == null) {
username = "";
}
if (tempPassword == undefined) {
password = "";
} else {
password = tempPassword;
}
//user.password = password;
//username = user.username;
//password = user.password;
var action:String = "Login";
var parameters:String = ""+username+""+password+"";
if (variables != undefined) {
parameters += "";
for (var i in variables) {
parameters += "";
parameters += ""+i+"";
parameters += ""+variables[i]+"";
parameters += "";
}
parameters += "";
}
send(action, parameters);
}
/*
Connects you to the server
@description Creates a socket connection with ElectroServer using an IP and Port specified. Alternatively, the
ip and port can be set using the {@link #setIP} and {@link #setPort} methods and left blank in this method.
See also {@link #onConnection}.
Explanation for beginners
ElectroServer is a socket-server, a piece of software written in Java that resides on a remote server
somewhere (or your own personal computer for testing). When the ElectroServer software is started
it "binds" itself to a specific IP address and "listens" for communication requests over a specific port.
The connect() method is used to establish a connection with ElectroServer. By specifying the IP address and
port that ElectroServer uses you can connect to it. This connection is called a persistent connection. It is
persistent because the connection exists until it is closed by the Flash client, the server, or by killing
the Flash client (leaving the web page).
While this connection exists data can be passed from the Flash client to the server or from the server
to the Flash client without either side requesting the data. This data is intercepted and used by making
use of many of the various methods and events of the ElectroServer object.
If you are truly a beginner and are having trouble understanding all of this, then please take a look at
some open-source FLA examples that use the ElectroServer class.
@param The ip address of ElectroServer
@param The port over which ElectroServer is listening
@example
Usage 1:
es.setIP("127.0.0.1");
es.setPort(9875);
es.connect();
Usage 2:
es.connect("127.0.0.1", 9875);
*/
public function connect(tmp_ip:String, tmp_port:Number) {
if (tmp_ip != undefined) {
setIP(tmp_ip);
}
if (tmp_port != undefined) {
setPort(tmp_port);
}
//Override the XMLSocket connect method
onConnect = connectionResponse;
onXML = XMLReceived;
super.connect(getIP(), getPort());
}
/*
Returns a reference to the object that represents you
@description Every user in the userlist has an object that contains information about that user. This method
returns the object that represents you.
Properties on user object
Name.value The username
userVariables Uservariables associated with you. See {@link #createUserVariable}.
AssignedNumber.value If the room is numbering users, then this has your unique number in it.
@example
The following just traces your username:
trace(es.getUser().Name.value);
The following returns the number associated with you in a game.
var myNum:Number = es.getUser().AssignedNumber.value;
@returns Returns an object representing you.
*/
public function getUser() {
return myUser;
}
private function applyAction(action:String, params:Object, originalXML:XML) {
if (action == "ConnectionResponse") {
//This is a willful response from the server
var Major:Number = Number(params.Version.attributes.Major);
var Minor:Number = Number(params.Version.attributes.Minor);
var Sub:Number = Number(params.Version.attributes.Sub);
if (params.Result.value == "Accepted" && ValidateVersion(Major, Minor, Sub)) {
connectionEstablished(true);
} else {
//did not connect properly
if (params.Result.value == "Accepted" && !ValidateVersion(Major, Minor, Sub)) {
var error = "ElectroServer 3 version is too old. Please install latest.";
trace("=====================================================");
trace("===============Error Error Error=====================");
trace("This class file is newer than the version of ElectroServer 3 that you are using.");
trace("AS 2.0 Class version: "+MajorVersion+"."+MinorVersion+"."+SubVersion);
trace("ElectroServer version: "+Major+"."+Minor+"."+Sub);
trace("If it says NaN above, then you definately need to update.");
trace("Visit http://www.electrotank.com/ElectroServer/");
trace("=====================================================");
trace("=====================================================");
} else {
var error = params.Reason.value;
}
connectionEstablished(false, error);
}
} else if (action == "LoginResponse") {
if (params.Result.value.toLowerCase() == "accepted") {
//var variables_array:Array = params.Variables.Variables;
var variables:Array = params.Variables.Variables;
var var_ob:Object = new Object();
if (params.Username.value != undefined) {
username = params.Username.value;
}
for (var j=0;j-1 && auto_join) {
joinRoom(pendingRoom, "", pendingZone);
}
} else {
//Success, do nothing
}
} else if (action == "LoadConfiguration") {
//This is for admin
var num_packets:String = params.NumberOfPackets.value;
var num:String = params.PacketNumber.value;
var packetData:String = params.PacketData.value;
if (num == "1") {
configXML = packetData;
} else {
configXML += packetData;
}
if (num == num_packets) {
parseConfig(configXML);
}
} else if (action == "UpdateUserVariable") {
var users = zone.users;
var ob = params.UserVariable;
var tmp_user = ob.User.value;
var value = ob.Data.value;
var name = ob.Name.value;
for (var i = 0; i2) {
var foo:Wddx = new Wddx();
var ob:Object = foo.deserialize(WDDXxml);
} else {
var ob:Object = new Object();
}
tmp_rooms[i].Description = ob;
//var room:Object = zone.rooms[i];
//room.data = room;
}
onRoomsInZoneLoaded(tmp_rooms, params.Zone.Name.value);
} else if (action == "RoomList") {
var myOldRoom = getRoom();
var oldUsers = getUserList();
zone = new Object();
zone.numUsers = Number(params.Zone.attributes.Users);
zone.name = params.Zone.Name.value;
zone.rooms = params.Zone.Rooms.Rooms;
for (var i = 0; i2) {
var foo:Wddx = new Wddx();
var ob:Object = foo.deserialize(WDDXxml);
} else {
var ob:Object = new Object();
}
zone.rooms[i].Description = ob;
var room:Object = zone.rooms[i];
room.label = room.Name.value;
room.data = room;
if (myOldRoom.Name.value == room.Name.value) {
zone.rooms[i] = myOldRoom;
zone.myRoom = myOldRoom;
zone.users = oldUsers;
}
}
zoneChanged(zone.name);
roomListUpdated(zone.rooms, "all");
} else if (action == "UpdateUserList") {
var minorAction:String = params.MinorAction.value;
if (minorAction == "UserJoined") {
var users = zone.users;
var user = params.User;
//
var user_name = user.Name.value;
var uv = user.UserVariables.UserVariables;
user.userVariables = new Object();
for (var k = 0; k2) {
var foo:Wddx = new Wddx();
var ob:Object = foo.deserialize(WDDXxml);
} else {
var ob:Object = new Object();
}
roomOb.Description = ob;
break;
}
}
roomListUpdated(zone.rooms, "roomupdated", roomOb);
} else if (minorAction == "CreateRoom") {
//Add a new room to the room list
var roomOb:Object = newRoomOb;
roomOb.label = roomOb.Name.value;
roomOb.data = roomOb;
var WDDXxml:XML = roomOb.Description.value;
var ob:Object;
if (WDDXxml != undefined && WDDXxml != "") {
var foo:Wddx = new Wddx();
ob = foo.deserialize(WDDXxml);
} else {
ob = new Object();
}
roomOb.Description = ob;
zone.rooms.push(roomOb);
roomListUpdated(zone.rooms, "roomcreated", roomOb);
} else if (minorAction == "DeleteRoom") {
//Room that already exists was deleted
for (var j = 0; j