//=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+ //ElectroServer Class //XML Protocol Version 3.2.0 //ActionScript Version 1.0 //Author: Jobe Makar, jobe@electrotank.com //Company: Electrotank, Inc. http://www.electrotank.com // www.electro-server.com // //Last edit: 11/22/2005 // //-----Revision History--------- // 9/18/03 Officially released // 10/9/03 Added version detection. If class connects to an older ElectroServer 3 version then an error appears // 10/11/03 Fixed chat message bug. Messages that were only numberic (e.g. 12345678901234567890) were being parsed as numbers // 10/20/03 Fixed the way variables are parsed in incoming plugin messages // 12/21/03 Fixed loginResponse case sensitivity issue (now "accepted" or "Accepted" are valid) // 12/23/03 Changed the use of a local var called 'xml' to 'tmp_xml' because of class obsuring // 12/23/03 Added setDebug(true|false) method. Default is false. If true, inbound and outbound messages are traced // 12/27/03 getRoomsInZone("zonename") added. onRoomsInZoneLoaded event added. onRoomsinZoneLoaded(room_list, zone_name) // 1/19/04 User variable fixes added. Each user object has a UserVariables object contained within, which contains the variables // 2/24/04 getLoggedInUserCount() added, callback: loggedInUserCountUpdated -- total number of users logged into the server, all zones // 2/26/04 Modified code for a hidden room work around. // 8/29/04 Fixed user variable 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 usersInRoomLoade event by also sending zone name and room name // 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/20/2005 Fixed userLocationLoaded bug fixed // 2/20/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 // 11/22/2005 Fixed two user variable bugs. // // //!!! Download ElectroServer class updates from here: http://www.electro-server.com/downloads.aspx // //=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+=~=+ #include "as_files/WDDX_mx.as" ElectroServerAS = function () { // Constructor for ElectroServerAS v3.0 object this.MajorVersion = 3; this.MinorVersion = 1; this.SubVersion = 0; this.debug = false; _global.ElectroServer = this; this.user = new Object(); this.isConnected = false; this.buddyList = new Array(); this.nodeNameList = {Users:true, Zones:true, UserVariables:true, RoomVariables:true, Rooms:true, Variables:true, BannedUsers:true, Plugins:true, Moderators:true, Words:true, RootWords:true, Templates:true}; }; ElectroServerAS.prototype.onFirstConnect = function(success) { //hidden //The true sign of being able to connect to ElectroServer is that ElectroServer sends //an XML packet back to the client. But this event is triggered the socket connection //itself is accepted. If success == false then there is a firewall issue or the server is down if (!success) { var error = "Was not able to connect to the server."; this.where.isConnected = false; this.where.onConnect(success, error); } }; ElectroServerAS.prototype.assignUserLabel = function(user) { if (user.attributes.Moderator) { user.icon = "electro"; if (user.Name.value.toLowerCase() == "jobe") { user.icon = "jobe"; } else if (user.Name.value.toLowerCase() == "mike") { user.icon = ""; } else if (user.Name.value.toLowerCase() == "aloeen") { user.icon = ""; } user.iconAlignment = "left"; } }; ElectroServerAS.prototype.setDebug = function(val) { this.debug = val; }; ElectroServerAS.prototype.getDebug = function() { return this.debug; }; ElectroServerAS.prototype.ValidateVersion = function(Major, Minor, Sub) { var ReturnVal = true; if (this.MajorVersion>Major || isNaN(Major)) { ReturnVal = false; } else if (this.MinorVersion>Minor && this.MajorVersion == Major) { ReturnVal = false; } else if (this.SubVersion>Sub && this.MinorVersion == Minor) { ReturnVal = false; } return ReturnVal; }; ElectroServerAS.prototype.pluginRequest = function(plugin, method, parameters) { var action = "ExecutePlugin"; var variableXML = ""; if (parameters != undefined) { variableXML = ""; for (var i in parameters) { variableXML += ""+i+""+parameters[i]+""; } variableXML += ""; } var parameters = ""+plugin+""+method+""+variableXML; this.send(action, parameters); }; //getLoggedInUserCount ElectroServerAS.prototype.getLoggedInUserCount = function() { var action = "GetLoggedInUserCount"; var parameters = ""; this.send(action, parameters); }; ElectroServerAS.prototype.getServerTime = function() { var action = "GetServerTime"; var parameters = ""; this.send(action, parameters); }; ElectroServerAS.prototype.getUsersInRoom = function(zone, room) { var action = "GetUsersInRoom"; var parameters = ""+zone+""+room+""; this.send(action, parameters); }; ElectroServerAS.prototype.getUserLocation = function(name) { var action = "GetUserLocation"; var parameters = ""+name+""; this.send(action, parameters); }; ElectroServerAS.prototype.terminateHere = function(xml) { //hidden //This is used by parseParameters to determine how deep the XML goes return xml.childNodes[0].hasChildNodes() ? false : true; }; ElectroServerAS.prototype.xmlReceived = function(data) { //hidden //Every packet of XML that is pushed in from the server hits this method forist var where = this.where; if (where.debug) { trace("-----incomming----"); trace(data); } var info = data.firstChild.childNodes; //Every XML packet has an action var action = info[0].firstChild.nodeValue.toLowerCase(); //Parse the parameters into easy-to-use data objects var parameters = info[1].childNodes; var params = new Object(); where.parseParameters(parameters, params, where); //Apply the action where.applyAction(action, params, where); }; ElectroServerAS.prototype.isArrayNodeName = function(nodeName, where) { //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 (where.nodeNameList[nodeName]) { return true; } else { return false; } }; ElectroServerAS.prototype.parseParameters = function(info, parentOb, where) { //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; i"+this.user.password+"ssss"; var parameters = ""+this.user.username+""+this.user.password+""; if (variables != undefined) { parameters += ""; for (var i in variables) { parameters += ""; parameters += ""+i+""; parameters += ""+variables[i]+""; parameters += ""; } parameters += ""; } this.send(action, parameters); }; ElectroServerAS.prototype.loadConfiguration = function() { var action = "LoadConfiguration"; var parameters = ""; this.send(action, parameters); }; ElectroServerAS.prototype.adminLogin = function(username, password) { this.user.username = username; if (password == undefined) { password = ""; } this.user.password = password; this.username = this.user.username; this.password = this.user.password; var action = "AdminLogin"; var parameters = ""+this.user.username+""+this.user.password+""; this.send(action, parameters); }; ElectroServerAS.prototype.deleteRoomVariable = function(name) { var action = "DeleteRoomVariable"; var parameters = ""+name+""; this.send(action, parameters); }; ElectroServerAS.prototype.changeRoomDetail = function(detail, value) { var action = "ChangeRoomDetails"; var minorAction; var field; var detail = detail.toLowerCase(); var pwordXML = ""; 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 = value; } else if (detail == "hidden") { minorAction = "ChangeVisibility"; field = "Hidden"; var descXML = value; } else if (detail == "capacity") { minorAction = "ChangeCapacity"; filed = "Capacity"; if (value == undefined || value == 0) { value = -1; } var descXML = value; } else if (detail == "password") { minorAction = "ChangePasswordProtected"; field = "Password"; var descXML = value; if (value == undefined) { value = ""; } if (value.length>=1) { var protected = true; } else { var protected = false; } pwordXML = ""+protected+""; } var parameters = ""+minorAction+""+pwordXML+"<"+field+">"+descXML+""; this.send(action, parameters); }; ElectroServerAS.prototype.kick = function(name, reason) { if (reason == undefined) { reason = ""; } var action = "ModeratorCommand"; var parameters = "Kick"+name+""+reason+""; this.send(action, parameters); }; ElectroServerAS.prototype.getBuddyList = function() { return this.buddyList; }; ElectroServerAS.prototype.addBuddy = function(name) { var buddyExists:Boolean = false; for (var i=0;i"; this.send(action, parameters); } }; ElectroServerAS.prototype.removeBuddy = function(name) { for (var i=0;i"; this.send(action, parameters); }; ElectroServerAS.prototype.ban = function(name, reason, expires) { if (reason == undefined) { reason = ""; } if (expires == undefined) { expires = "-1"; } var action = "ModeratorCommand"; var parameters = "Ban"+name+""+reason+""+expires+""; this.send(action, parameters); }; ElectroServerAS.prototype.updateUserVariable = function(name, value) { var action = "UpdateUserVariable"; var parameters = "Update"+name+""+value+""; this.send(action, parameters); }; ElectroServerAS.prototype.deleteUserVariable = function(name) { var action = "DeleteUserVariable"; var parameters = ""+name+""; this.send(action, parameters); }; ElectroServerAS.prototype.createUserVariable = function(name, value) { var action = "UpdateUserVariable"; var parameters = "Create"+name+""+value+""; this.send(action, parameters); }; ElectroServerAS.prototype.createRoomVariable = function(ob) { var name = ob.name; var data = ob.data; var persistent = ob.persistent; var locked = ob.locked; if (persistent == undefined) { persistent = false; } if (locked == undefined) { locked = false; } if (this.zone.myRoom.roomVariables[name] == undefined) { var action = "CreateRoomVariable"; var parameters = ""+name+""; } else { var action = "UpdateRoomVariable"; var parameters = ""+name+""; } this.send(action, parameters); }; ElectroServerAS.prototype.send = function(action, parameters) { //hidden var message = ""+action+""+parameters+""; if (this.debug) { trace("---out going----"); trace(message); } this.server.send(message); }; ElectroServerAS.prototype.close = function() { this.server.close(); this.onClose(false); }; ElectroServerAS.prototype.serverClosedConnection = function() { this.where.onClose(true); }; ElectroServerAS.prototype.connect = function(ip, port) { if (ip != undefined) { this.setIP(ip); } if (port != undefined) { this.setPort(port); } this.connected = false; this.server = new XMLSocket(); this.server.where = this; this.server.onConnect = this.onFirstConnect; this.server.onXML = this.xmlReceived; this.server.onClose = this.serverClosedConnection; this.server.connect(this.ip, this.port); }; ElectroServerAS.prototype.setIP = function(ip) { this.ip = ip; }; ElectroServerAS.prototype.getIP = function() { return this.ip; }; ElectroServerAS.prototype.setPort = function(port) { this.port = port; }; ElectroServerAS.prototype.getPort = function() { return this.port; }; ElectroServerAS.prototype.getZone = function() { return this.zone; }; ElectroServerAS.prototype.joinGame = function(room, password, type, zone) { var type = type.toLowerCase(); if (type == "player" || type == undefined) { var numbered = true; } else if (type == "spectator") { var numbered = false; } this.joinRoom(room, password, zone, numbered); this.inGame = true; }; ElectroServerAS.prototype.joinRoom = function(room, password, zone, numbered) { var action = "JoinRoom"; if (numbered == undefined) { numbered = true; } if (password == undefined) { password = ""; } if (zone == undefined) { zone = this.zone.name; } this.pendingRoom = room; this.inGame = false; this.creatingRoom = false; var parameters = ""+zone+""+room+""+password+""+numbered+""; this.send(action, parameters); }; ElectroServerAS.prototype.sendMessage = function(type, message, users, variables) { var type = type.toLowerCase(); if (type == "public" || type == "all") { //'users' is actually the variables for public messages this.sendPublicMessage(message, users); } else if (type == "private") { this.sendPrivateMessage(message, users, variables); } }; ElectroServerAS.prototype.sendPublicMessage = function(message, variables) { var action = "SendPublicMessage"; //var parameters = "Test VarYaya"; var variableXML = ""; for (var i in variables) { var name = i; var value = variables[i]; variableXML += ""+name+""; } if (variableXML != "") { variableXML = ""+variableXML+""; } else { variableXML = ""; } var parameters = ""+variableXML; this.send(action, parameters); }; ElectroServerAS.prototype.sendPrivateMessage = function(message, users, variables) { var action = "SendPrivateMessage"; var usersXML = ""; for (var i = 0; i"; } usersXML += ""; var variableXML = ""; for (var i in variables) { var name = i; var value = variables[i]; variableXML += ""+name+""; } if (variableXML != "") { variableXML = ""+variableXML+""; } else { variableXML = ""; } var parameters = usersXML+""+variableXML; this.send(action, parameters); }; ElectroServerAS.prototype.cancelChallenge = function() { this.challenging = false; delete this.opponent; var ob = new Object(); ob.action = "challengecancelled"; this.sendMove(who, ob); }; ElectroServerAS.prototype.sendChallenge = function(who, game) { var ob = new Object(); ob.action = "challenge"; ob.game = game; this.challenging = true; this.opponent = who; this.sendMove(who, ob); }; ElectroServerAS.prototype.sendAutoDecline = function(who) { var ob = new Object(); ob.action = "autodecline"; this.sendMove(who, ob); }; ElectroServerAS.prototype.sendDecline = function(who) { var ob = new Object(); ob.action = "decline"; this.sendMove(who, ob); }; ElectroServerAS.prototype.sendMove = function(who, ob) { var wddxOb = new WDDX(); var moveXML = wddxOb.serialize(ob); if (who.toLowerCase() == "all") { var action = "SendPublicMessage"; //var parameters = "Test VarYaya"; var parameters = "ActionMoveMoveTypePublic"; } else { var action = "SendPrivateMessage"; var users = who; var usersXML = ""; for (var i = 0; i"; } usersXML += ""; var parameters = usersXML+"ActionMoveMoveTypePublic"; } this.send(action, parameters); }; ElectroServerAS.prototype.getRoomList = function() { return this.zone.rooms; }; ElectroServerAS.prototype.getRoom = function() { return this.zone.myRoom; }; ElectroServerAS.prototype.getUserList = function() { return this.zone.users; }; ElectroServerAS.prototype.createGameRoom = function(roomOb) { if (roomOb.attributes == undefined) { roomOb.attributes = new Object(); } roomOb.attributes.isGameRoom = true; if (roomOb.updatable == undefined) { roomOb.updatable = false; } roomOb.numbered = true; this.createRoom(roomOb); this.inGame = true; }; ElectroServerAS.prototype.createRoom = function(roomOb, auto_join) { //roomOb properties: zone, roomName, hidden, numbered, UserVariablesEnabled, Description //Password, Capacity, roomVariables if (auto_join == undefined || auto_join == "true") { auto_join = true; } else { auto_join = false; } this.auto_join = auto_join; var action = "CreateRoom"; var password = roomOb.password; var UserVariablesEnabled = roomOb.userVariablesEnabled; var hidden = roomOb.hidden; var zone = roomOb.zone; var roomName = roomOb.roomName; var numbered = roomOb.numbered; var capacity = roomOb.capacity; var description = roomOb.description; var roomVariables = roomOb.roomVariables; var updatable = roomOb.updatable; var plugins = roomOb.plugins; var descOb = new Object(); var FloodingFilterEnabled = roomOb.FloodingFilterEnabled; descOb.description = description; if (roomOb.attributes != undefined) { descOb.attributes = roomOb.attributes; } var wddxOb = new WDDX(); var descXML = wddxOb.serialize(descOb); if (zone == undefined) { zone = this.zone.name; } if (FloodingFilterEnabled == undefined) { FloodingFilterEnabled = true; } if (updatable == undefined) { updatable = true; } if (hidden == undefined) { hidden = false; } if (capacity == undefined) { capacity = -1; } if (numbered == undefined) { numbered = false; } if (description == undefined) { description = ""; } if (password == undefined) { password = ""; } if (UserVariablesEnabled == undefined) { UserVariablesEnabled = false; } if (roomVariables == undefined) { var roomVariableXML = ""; } else { var roomVariableXML = ""; for (var i = 0; i"; str += ""+name+""; str += ""; str += ""; roomVariableXML += str; } roomVariableXML += ""; } if (plugins == undefined) { var pluginXML = ""; } else { var pluginXML = ""; for (var i = 0; i"+pluginVarValue+""; } pluginVariablesXML += ""; } pluginXML += ""+name+""+pluginVariablesXML+""; } pluginXML += ""; } var parameters = ""+zone+""; this.joiningRoom = true; this.pendingRoom = roomName; this.pendingZone = zone; this.creatingRoom = true; this.inGame = false; this.send(action, parameters); }; ElectroServerAS.prototype.getRoomsInZone = function(tmp_zone) { this.send("GetRoomsInZone", ""+tmp_zone+""); }; ElectroServerAS.prototype.getAllZones = function() { this.send("GetAllZones", ""); }; ElectroServerAS.prototype.getUser = function() { return this.myUser; }; ElectroServerAS.prototype.getRoomVariables = function() { return this.zone.myRoom.roomVariables; }; ElectroServerAS.prototype.parseConfig = function(config, where) { XML.prototype.ignoreWhite = true; var temp = new XML(config); var params = new Object(); where.parseParameters(temp.firstChild.childNodes, params, where); where.configurationLoaded(params); }; ElectroServerAS.prototype.applyAction = function(action, params, where) { if (action == "connectionresponse") { //This is a willful response from the server var Major = Number(params.Version.attributes.Major); var Minor = Number(params.Version.attributes.Minor); var Sub = Number(params.Version.attributes.Sub); if (params.result.value == "Accepted" && where.ValidateVersion(Major, Minor, Sub)) { //properly connected where.connected = true; where.onConnect(true); where.isConnected = true; } else { if (params.result.value == "Accepted" && !where.ValidateVersion(Major, Minor, Sub)) { //version is too old 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: "+where.MajorVersion+"."+where.MinorVersion+"."+where.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 { //did not connect properly var error = params.reason.value; } trace("Connection failure!!!!!!!!!!!!!!!!!!!!!!!!"); where.isConnected = false; where.onConnect(false, error); } } else if (action == "getuserlocation") { var name = params.User.value var zone = params.Zone.value; var room = params.Room.value; //where.userLocationLoaded(name, zone, room); if (params.Status.value == "Success") { where.userLocationLoaded(name, zone, room, true); } else { where.userLocationLoaded(name, zone, room, false); } } else if (action == "getusersinroom") { var arr = params.Users.Users; var returnArr = new Array(); for (var i=0;i2) { var foo = new WDDX(); var ob = foo.deserialize(WDDXxml); } else { var ob = new Object(); } tmp_rooms[i].description = ob; } where.onRoomsInZoneLoaded(tmp_rooms, params.zone.name.value); } else if (action == "roomlist") { var myOldRoom = where.zone.myRoom; var oldUsers = where.zone.users; where.zone = new Object(); where.zone.users = oldUsers; var zone = where.zone; 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 = new WDDX(); var ob = foo.deserialize(WDDXxml); } else { var ob = new Object(); } zone.rooms[i].description = ob; if (room_name == myOldRoom.Name.value) { zone.myRoom = myOldRoom; zone.rooms[i] = myOldRoom; } } where.zoneChanged(zone.name); where.roomListUpdated(where.zone.rooms, "all"); } else if (action == "updateuserlist") { var minorAction = params.minorAction.value.toLowerCase(); if (minorAction == "userjoined") { var users = where.zone.users; var user = params.user; user.label = user.Name.value; // var user_name = user.Name.value; var uv = user.UserVariables.UserVariables; user.userVariables = new Object(); for (var k = 0; k2) { var foo = new WDDX(); var ob = foo.deserialize(WDDXxml); } else { var ob = new Object(); } roomOb.description = ob; break; } } where.roomListUpdated(where.zone.rooms, "roomupdated", roomOb); } else if (minorAction == "createroom") { //Add a new room to the room list var roomOb = newRoomOb; roomOb.label = roomOb.Name.value; roomOb.iconAlignment = "left"; var WDDXxml = roomOb.description.value; var foo = new WDDX(); var ob = foo.deserialize(WDDXxml); roomOb.description = ob; where.zone.rooms.push(roomOb); where.roomListUpdated(where.zone.rooms, "roomcreated", roomOb); } else if (minorAction == "deleteroom") { //Room that already exists was deleted for (var j = 0; j