Persistent Dyanmic Rooms comes true!

Post here your suggestions for new possible features in SmartFoxServer.

Moderators: Lapo, Bax

Do you like it?

Your are a god!
4
50%
Yeah, is cool.
4
50%
No, its awful!
0
No votes
 
Total votes: 8
Menser
Posts: 111
Joined: 13 Nov 2007, 18:32

Persistent Dyanmic Rooms comes true!

Postby Menser » 15 Nov 2007, 09:28

Hey Everyone-

So since a few others seemed interested in dynamic rooms that persist over server reboots, and i don't like waiting for things, i decided to write a little code to do just that. THis seemed like a good place to put it.

There is two parts.

The first is a a zone extension that handles the bulk of the work. I did a great bit of documentation (maybe to much, it was late) on the extension, but if anyone has any questions, please feel free to ask me.

The Second is two variables and a function that you will need to copy to your other extension in which you wish to add persistent dynamic rooms to. These are basically copies (with some trace stuff removed) of two variables and a function in the extension.

I will post the code for this in two separate replies to make it easier to separate. Im sure there is room for some optimization.

And YES, i do plan on extending this even further to include the saving and loading of room variables as well.

Questions, Comments, Ideas?

_-Menser-_


-----EDIT-----
Forgot to mention that you will need to create a "Rooms" directory in your Smart Fox server directory. It was hopefully pretty obvious, but just in case.
Last edited by Menser on 15 Nov 2007, 09:43, edited 2 times in total.
Menser
Posts: 111
Joined: 13 Nov 2007, 18:32

Postby Menser » 15 Nov 2007, 09:29

DynRooms.as

Code: Select all

/*************************************************************************
 * Created By: Menser
 * Date: Nov 15th, 2007
 * Email S t r i k e B a c k S t u d i o s @ g m a i l . c o m (without all the spaces)
 * Aim: CyphonWork
 *
 * Requires: SmartFox Server 1.4.5 or higher
 *
 * Purpose:
 * This extension will allow you to create rooms Dynamically on the server
 * and have them persist over server restarts.
 *
 * How it works:
 * Pretty simple really. It runs through the rooms, looking for ones we
 * designated as rooms to save. It then builds up a string containg the
 * variables for all the rooms that is deliminated by \n
 * We then use the servers built in file saving abilities and save that file
 * To load the rooms we simply read the file in and parse it to an array.
 * Since we are saving the file, we know that every X variables is one room,
 * and that each variable in an X segment of the array corresponds to a
 * particular room property.
 *
 * You should take into consideration where you place this extension
 * in your list for the zone extensions. Why? Extensions are loaded
 * in the order you have them in the config file. So if you have an
 * extension you want to do something when a dynamic room is created
 * youll need to make sure that extension is loaded before this one.
 * Or say you have an extension that might delete one of the Dynamically
 * loaded rooms, you will want to load that extension after this one,
 * since you will want to make sure this room is loaded.
 *
 * Pros:
 * Um, duh. Persitant Dyanmic rooms. What more could you ask for!
 
 * Cons:
 * This obviously has the downside of using up a tad bit more memory then
 * if SmartFox supported room saving nativley since i have to push off
 * certain variables of a room into its properties list so i can retreive
 * them later. I imagine that any impact this has is extremly MINIMAL though
 *
 * The second down side is that you have to copy the newCreateRoom function
 * to all of the other extension you may be using in order for this one to work
 * properly since it needs certain variables saved to a room which it does when
 * creating it.
 *
 * Obviously since these rooms are dynamically created, there is no guarentee
 * that their Room IDs will be the same everytime you start the server. So
 * you proabbly shouldnt depend on a partiuclar room being of a particular ID.
 *************************************************************************/


var RoomFolder = "Rooms/";            //This is the folder path to where the Room file sits
var RoomFile = RoomFolder + "Rooms.txt";   //This is the actual name of the file where rooms are saved
var DebugIt = true;                  //If we wish to display Messages from the extension


/*************************************************************************
 * The below to variables must be copied to whatever extension you will
 * be using the newCreateRoom function.
 *************************************************************************/
var defMaxUser = 50;               //Default maximum number of users in a room, used when inproper value passed
var defMaxSpec = 5;                  //Default maximum number of spectators in a room, used when inproper value passed

/*************************************************************************
 * The below variables are used for automatic saving of rooms.
 * I HIGHLY recommened you use the automatic saving of rooms. Why?
 * Cause otherwise not only do you need to copy the newCreateRoom function
 * to other extenstion you may wish to create dynamic rooms from, but by
 * not using the automatic saving, youll also have to copy the saveRooms
 * function to the other extensions as well.
 *************************************************************************/
var AutoSave = true;      // If you wish to use the automatic saver or not
var SaveTime = 60000;      // How often (in ms) you want the autosaver to fire
var SaveInt;            // The referance to the interval


function init()
{
   
   //newCreateRoom("Test", null, false, 10, 20, true, true, null, null, null);
   //newCreateRoom("Test2", null, false, 10, 20, true, true, null, null, null);
   LoadRooms();

   if (AutoSave == true)
   {
      dynTrace("[AUTOMATIC ROOM SAVING ON] Fires Every " + SaveTime + "ms");
      SaveInt = setInterval("SaveRooms", SaveTime);
   }else
   {
      dynTrace("[AUTOMATIC ROOM SAVING OFF]");
   }
}


function destroy()
{
   if (AutoSave == true)
      clearInterval(SaveInt);
}

function handleInternalEvent(evt)
{
   //We dont use the newRoom event because im almost certain
   //that the event will fire as soon as i call _server.createRoom()
   //which would then cause this code to execute before i put the
   //properties on the room telling it it needs to be saved.
}

function handleRequest(cmd, params, user, fromRoom)
{
}

function dynTrace(Message)
{
   if (DebugIt == true)
   {
      trace("[DynRoom] " + Message);
   }
}

/*************************************************************************
 * Name: newCreateRoom
 * Parameters
 *      rName   (String)      This is the name of the room to be created.
 *      rPass   (String|null) This is the password required to enter the room.
 *      rGame   (Boolean)     This is if the room is a game room or not.
 *      rMaxU   (Number)      The maximum number of users in the room.
 *      rMaxS   (Number)      The maximum number of spectators in the room.
 *      sUpdate (Boolean)     If the server will send update to clients notifying of room creation.
 *      bEvt    (Boolean)     If the server broadcasts the event for the creation of a new room.
 *      rxName  (String|null) Referance Name of the extension the room should load.
 *      rxClass (String|null) Name of he .as file the server should load for the extension
 *
 */
function newCreateRoom(rName, rPass, rGame, rMaxU, rMaxS, sUpdate, bEvt, rxName, rxClass)
{
   dynTrace("[CREATE ROOM] " + rName);
   
   
   var roomObj = {}


   
   /*************************************************************************
    * Here we do a little error checking, make sure nothing to crazy is
    * getting passed along
    *************************************************************************/
   if ((rName == null) || (rName == ""))
   {
      dynTrace("[ERROR] Attempting to create room with null name.");
      return;
   }
   
   if (Number(rMaxU) == Number.NaN)
   {
      rMaxU = defMaxUser;
      dynTrace("[ERROR] [CREATE ROOM] [ROOM: " + rName + "] Max User NaN, using default.");
   }
      
   if (Number(rMaxS) == Number.NaN)
   {
      rMaxS = defMaxSpec;
      dynTrace("[ERROR] [CREATE ROOM] [ROOM: " + rName + "] Max Spectator NaN, using default.");
   }
   
   roomObj.name = rName;
   roomObj.maxU = Number(rMaxU)
   roomObj.maxS = Number(rMaxS);
   roomObj.isGame = Boolean(rGame);
   
   if ((rPass != null) && (rPass != ""))
      roomObj.pwd = rPass;
   
   //We only save the extension data if both parts are there.
   if ((rxName != null) && (rxClass != null))
   {
      roomObj.xtName = rxName;
      roomObj.xtClass = rxClass;
   }

   //Here we actually create the new room
   var newRoom = _server.createRoom(roomObj, null, sUpdate, bEvt, null, null);
   
   /*************************************************************************
    * Here we push off a few variables into the room itself.
    * Im assinging the variables to the room after we create it, because for
    * some reason trying to assign them via the roomVars parameter of
    * createRoom was not working.
    *************************************************************************/
   newRoom.properties.put("Save", true);
   newRoom.properties.put("MaxUsers", rMaxU);
   newRoom.properties.put("MaxSpec", rMaxS);
   newRoom.properties.put("xtName", rxName);
   newRoom.properties.put("xtClass", rxClass);
   newRoom.properties.put("sUpdate", sUpdate);
   newRoom.properties.put("bEvt", bEvt);

   /*************************************************************************
    * This has been commented out since i came up with the Atomatic saving
    * idea feature. Obviously if you do not wish to use the AutoSave feature
    * then you will need to uncomment this line, and copy the saveRooms
    * function as well as this one to the other extensions you wish to use
    *************************************************************************/
   //SaveRooms();
   
   
   
   
}


function SaveRooms()
{
   var Rooms = _server.getCurrentZone().getRooms();
   
   var i = 0;
   var OutputTxt = "";
   
   for (i = 0; i < Rooms.length; i++)
   {
      var Room = Rooms[i];
      var Save = Room.properties.get("Save")
      if (Save == true)
      {
         var RoomName = Room.getName();
         var Pass = Room.getPassword();
         var iGame = Room.isGame();
         var MaxUsers = Room.properties.get("MaxUsers");
         var MaxSpec = Room.properties.get("MaxSpec");
         var xtName = Room.properties.get("xtName");
         var xtClass = Room.properties.get("xtClass");
         var sUpdate = Room.properties.get("sUpdate");
         var bEvt = Room.properties.get("bEvt");
         
         dynTrace("[SAVE ROOM] " + RoomName);
         
         OutputTxt += "\n" + RoomName + "\n" + Pass + "\n" + iGame + "\n" + MaxUsers + "\n" + MaxSpec + "\n" + xtName + "\n" + xtClass + "\n" + sUpdate + "\n" + bEvt;
         
      }
      
   }
   /*************************************************************************
    * Checks for & Removes the old room file
    * Below was commented out because (on windows atleast) writing
    *************************************************************************/

   //if (_server.fileExist(RoomFile) == true)
   //   _server.removeFile(RoomFile);

   //Save the new one
   _server.writeFile(RoomFile, OutputTxt);
   
}

function LoadRooms()
{
   //make sure the file Exists
   if (_server.fileExist(RoomFile) == false)
      return;
      
   var InputTxt = _server.readFile(RoomFile);

   //Makes sure the file isnt empty
   if (InputTxt == null)
      return;
      
      
   var i = 0;

   var InLines = InputTxt.split("\n");

   //We start on 1 since we always write a \n to the start of each new room
   for (i = 1; i < InLines.length; i+= 9)
   {
      var rName = InLines[i];
      var rPass = InLines [i + 1];
      var rGame = InLines [i + 2];
      var rUsers = InLines [i + 3];
      var rSpec = InLines [i + 4];
      var rxName = InLines [i + 5];
      var rxClass = InLines [i + 6];
      var sUpdate = InLines [i + 7];
      var bEvt = InLines [i + 8];
      
      dynTrace("[LOADING ROOM] " + rName);
      
      //Below we just set the variables to the right type, since when they
      //are read from the file they are strings.
      
      if (rGame == "false")
         rGame = false;
      else
         rGame = true;
         
      if (sUpdate == "false")
         sUpdate = false;
      else
         sUpdate = true;
         
      if (bEvt == "false")
         bEvt = false;
      else
         bEvt = true;
         
      if (rPass == "null")
         rPass = null;
      if (rxName == "null")
         rxName = null;
      if (rxClass == "null")
         rxClass = null;
         
      if (Number(rUsers) == Number.NaN)
      {
         rUsers = defMaxUser;
         dynTrace("[ERROR] [LOAD ROOM] [ROOM: " + rName + "] Max User NaN, using default.");
      }
         
      if (Number(rSpec) == Number.NaN)
      {
         rSpec = defMaxSpec;
         dynTrace("[ERROR] [LOAD ROOM] [ROOM: " + rName + "] Max Spectator NaN, using default.");
      }
         
         
      //Here we call our newCreateRoom function so that we make sure to save the rooms we just loaded.
      newCreateRoom(rName, rPass, rGame, rUsers, rSpec, sUpdate, bEvt, rxName, rxClass);
   }
   
}
Last edited by Menser on 15 Nov 2007, 10:56, edited 1 time in total.
Menser
Posts: 111
Joined: 13 Nov 2007, 18:32

Postby Menser » 15 Nov 2007, 09:31

variables and function to copy to your other extensions.

Code: Select all

var defMaxUser = 50;
var defMaxSpec = 5;

function newCreateRoom(rName, rPass, rGame, rMaxU, rMaxS, sUpdate, bEvt, rxName, rxClass)
{

   var roomObj = {}

   if ((rName == null) || (rName == ""))
   {
      return;
   }
   
   if (Number(rMaxU) == Number.NaN)
   {
      rMaxU = defMaxUser;
   }
      
   if (Number(rMaxS) == Number.NaN)
   {
      rMaxS = defMaxSpec;
   }
   
   roomObj.name = rName;
   roomObj.maxU = Number(rMaxU)
   roomObj.maxS = Number(rMaxS);
   roomObj.isGame = Boolean(rGame);
   
   if ((rPass != null) && (rPass != ""))
      roomObj.pwd = rPass;
   

   if ((rxName != null) && (rxClass != null))
   {
      roomObj.xtName = rxName;
      roomObj.xtClass = rxClass;
   }


   var newRoom = _server.createRoom(roomObj, null, sUpdate, bEvt, null, null);
   
   newRoom.properties.put("Save", true);
   newRoom.properties.put("MaxUsers", rMaxU);
   newRoom.properties.put("MaxSpec", rMaxS);
   newRoom.properties.put("xtName", rxName);
   newRoom.properties.put("xtClass", rxClass);
   newRoom.properties.put("sUpdate", sUpdate);
   newRoom.properties.put("bEvt", bEvt);

   /*************************************************************************
    * This has been commented out since i came up with the Atomatic saving
    * idea feature. Obviously if you do not wish to use the AutoSave feature
    * then you will need to uncomment this line, and copy the saveRooms
    * function as well as this one to the other extensions you wish to use
    *************************************************************************/
   //SaveRooms();
   
   
   
   
}
User avatar
alcho
Posts: 84
Joined: 02 Dec 2006, 19:37
Location: UK
Contact:

Postby alcho » 15 Nov 2007, 10:53

wow great work!
Its all about the SmartFox!
UrbaLoca
Posts: 86
Joined: 29 Nov 2006, 16:44

Postby UrbaLoca » 01 Oct 2008, 21:39

What is the createRoom(); funcion to create the room?
Menser
Posts: 111
Joined: 13 Nov 2007, 18:32

Postby Menser » 20 Oct 2008, 04:00

Hey-

Sorry for the delayed response, i have been away for a awhile and did not have internet access.

I assume your talking about the _server.createRoom function..
If that is the case then yes, it is the command tell the server to create a new room.

Hope that clarifies it some.

_-Menser-_
x.Mara.x
Posts: 23
Joined: 18 Dec 2008, 20:03

Postby x.Mara.x » 19 Dec 2008, 20:38

n00b question:

How do i implement it? i mean.. i got the DynRooms.as
and then in the config file i put:

<Zone name="simpleChat" uCountUpdate="true" buddyList="20" maxUsers="4000" customLogin="false">
<Rooms>
<Room name="The Hall" maxUsers="50" isPrivate="false" isTemp="false" autoJoin="true" uCountUpdate="true" />
<Room name="The Kitchen" maxUsers="50" isPrivate="false" isGame="false" isTemp="false" />
<Room name="The Garden" maxUsers="50" isPrivate="false" isTemp="false" />
<Room name="The Bathroom" maxUsers="50" isPrivate="false" isTemp="false" />
<Room name="The Garage" maxUsers="50" isPrivate="false" isTemp="false" />
<Room name="The Living Room" maxUsers="50" isPrivate="true" isTemp="false" pwd="test" />
</Rooms>


<Moderators status="on">
<Mod name="modName" pwd="modPass" />
</Moderators>
<Extensions>
<extension name="DynRooms" className="DynRooms.as" type="script" />
<extension name="json" className="jsonSample.as" type="script" />
<extension name="smartMessenger" className="smartMessenger.as" type="script" />
</Extensions>
</Zone>



I put the code you said to put in the other extensions such as simpleExt.as .. and i put:

Code: Select all

on(release) {
          var room:Object = {}

   room.rName = "hello"
   room.rPass = "boo"
   room.rMaxU = 25

   
    room.rxName = "DynRooms" // also tried with casas.as
   room.rxClass = "DynRooms.as"// also tried with casas.as
           smartfox.sendXtMessage("DynRooms", newCreateRoom(), room)
}

in my file but
it returns:
[Sending]: <msg t='xt'><body action='xtReq' r='4'><![CDATA[<dataObj><var n='name' t='s'>DynRooms</var><obj t='o' o='param'><var n='rxClass' t='s'>DynRooms.as</var><var n='rxName' t='s'>DynRooms</var><var n='rMaxU' t='n'>25</var><var n='rPass' t='s'>boo</var><var n='rName' t='s'>hello</var></obj></dataObj>]]></body></msg>
[

but nothing is written in the Rooms.txt file :/ i am guessing that the name of the variables are not correct.. which would be correct?

Plus.. nothing shows in the Server..
Menser
Posts: 111
Joined: 13 Nov 2007, 18:32

Postby Menser » 05 Jan 2009, 02:38

Hello-

Sorry for the long response time, just not keeping up like i used to.
Anyways, the reason its not working is that it looks like your trying to call it from the client side.

If i remember correctly it does not support creating and saving rooms from the client side. THis was because i saw this feature possibly being abused by not so nice users to generate as many persistent rooms as they wanted.

It might be able to create them though, you would have to look into the variables i set on a room when i create it, and then make sure to put those variables on the room you are creating. Then as long as you have autosave feature on (Which it is by default) it should be saving the room.

Hope that helps some, i know its abit vague but its been ages since i looked at this code.

If you need any more help jsut let me know.

_-Menser-_

Return to “Features Wish List”

Who is online

Users browsing this forum: No registered users and 11 guests