Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Smartfoxserver 2x

Discussion in 'Multiplayer' started by DevionGames, Jun 21, 2011.

  1. DevionGames

    DevionGames

    Joined:
    Feb 22, 2010
    Posts:
    1,624
    SmartFoxServer 2x​

    1. Setup
    2. Connect GUI
    3. Handling Information between Server and Client

    1. Setup

    - download the SmartFoxServer 2x here .
    - install the server on your desktop.
    - start the server
    - open the admin tool with typing in your browser http://localhost:8080/admin/
    - connect to server
    - default Username/Password:
    Username: sfsadmin Password: sfsadmin



    - go to Administration modules --> Server Configurator
    - add a new socketaddress, same ip, port type = UDP



    - don't forget to submit

    - I get the basics for the connect/login from the FPS Demo, which can be downloaded here

    - in the folder SFS2x you will find a new folder with the name extensions open the folder and put in it the folder from the FPS Demo called SFS2XFPSextension
    - you can give this folder a name you like
    - now open the project "SFS2XFPSTutorial" with unity3d
    - go to the NetworkManager.cs and change the name

    Code (csharp):
    1. public readonly static string ExtName = "tng";//  <----this is the SFS2XFPSextension folder if you renamed it  , then put the current name here
    - thats all on the configuration part, you can start the server and login.

    2. Connect GUI
    You can change the Connect/Login phase like you want i do it this way, because i do not like the "chatroom " in the demo:

    LobbyGUI.cs
    Code (csharp):
    1. using System.Text;
    2. using Sfs2X;
    3. using Sfs2X.Core;
    4. using Sfs2X.Entities;
    5. using Sfs2X.Requests;
    6. using Sfs2X.Logging;
    7.  
    8.  
    9. public class LobbyGUI : MonoBehaviour {
    10.  
    11.     private SmartFox smartFox;
    12.     private string zone = "SimpleChat";
    13.     public string serverName = "127.0.0.1";
    14.     public int serverPort = 9933;
    15.     private string username = "";
    16.     private string userpassword="";
    17.     private string loginErrorMessage = "";
    18.     public int areaHeight = 240;
    19.     public int areaWidth = 200;
    20.     public Texture2D background;
    21.     private ArrayList messages = new ArrayList();
    22.     private System.Object messagesLocker = new System.Object();
    23.     public GUISkin gSkin;
    24.  
    25.     void Start()
    26.     {
    27.         bool debug = false;
    28.         if (SmartFoxConnection.IsInitialized)
    29.         {
    30.             smartFox = SmartFoxConnection.Connection;
    31.         }
    32.         else
    33.         {
    34.             smartFox = new SmartFox(debug);
    35.         }
    36.            
    37.         smartFox.AddLogListener(LogLevel.INFO, OnDebugMessage);
    38.     }
    39.    
    40.     void FixedUpdate() {
    41.         smartFox.ProcessEvents();
    42.     }
    43.    
    44.     #region Callbacks
    45.    
    46.     private void AddEventListeners() {
    47.        
    48.         smartFox.RemoveAllEventListeners();
    49.        
    50.         smartFox.AddEventListener(SFSEvent.CONNECTION, OnConnection);
    51.         smartFox.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
    52.         smartFox.AddEventListener(SFSEvent.LOGIN, OnLogin);
    53.         smartFox.AddEventListener(SFSEvent.LOGIN_ERROR, OnLoginError);
    54.         smartFox.AddEventListener(SFSEvent.LOGOUT, OnLogout);
    55.         smartFox.AddEventListener(SFSEvent.ROOM_JOIN, OnJoinRoom);
    56.         smartFox.AddEventListener(SFSEvent.PUBLIC_MESSAGE, OnPublicMessage);
    57.        
    58.         smartFox.AddEventListener(SFSEvent.ROOM_CREATION_ERROR, OnCreateRoomError);
    59.         smartFox.AddEventListener(SFSEvent.USER_ENTER_ROOM, OnUserEnterRoom);
    60.         smartFox.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnUserLeaveRoom);
    61.         smartFox.AddEventListener(SFSEvent.ROOM_ADD, OnRoomAdded);
    62.         smartFox.AddEventListener(SFSEvent.ROOM_REMOVE, OnRoomDeleted);
    63.         smartFox.AddEventListener(SFSEvent.USER_COUNT_CHANGE, OnUserCountChange);
    64.         smartFox.AddEventListener(SFSEvent.UDP_INIT, OnUdpInit);
    65.     }
    66.    
    67.     private void UnregisterSFSSceneCallbacks() {
    68.         smartFox.RemoveAllEventListeners();
    69.     }
    70.    
    71.     public void OnConnection(BaseEvent evt) {
    72.         bool success = (bool)evt.Params["success"];
    73.         if (success) {
    74.             SmartFoxConnection.Connection = smartFox;
    75.             Debug.Log("Connected...");
    76.             isConnected=true;
    77.             smartFox.Send(new LoginRequest(username, "", zone));
    78.         }
    79.     }
    80.  
    81.     public void OnConnectionLost(BaseEvent evt) {
    82.         UnregisterSFSSceneCallbacks();
    83.     }
    84.  
    85.     public void OnLogin(BaseEvent evt) {
    86.         try {
    87.             if (evt.Params.ContainsKey("success")  !(bool)evt.Params["success"]) {
    88.                 loginErrorMessage = (string)evt.Params["errorMessage"];
    89.                 Debug.Log("Login error: "+loginErrorMessage);
    90.             }
    91.             else {
    92.                 Debug.Log("Logged in successfully");
    93.                 // Startup up UDP
    94.                 smartFox.InitUDP(serverName, serverPort);
    95.             }
    96.         }
    97.         catch (Exception ex) {
    98.             Debug.Log("Exception handling login request: "+ex.Message+" "+ex.StackTrace);
    99.         }
    100.     }
    101.  
    102.     public void OnLoginError(BaseEvent evt) {
    103.         Debug.Log("Login error: "+(string)evt.Params["errorMessage"]);
    104.     }
    105.    
    106.     public void OnUdpInit(BaseEvent evt) {
    107.         if (evt.Params.ContainsKey("success")  !(bool)evt.Params["success"]) {
    108.             loginErrorMessage = (string)evt.Params["errorMessage"];
    109.             Debug.Log("UDP error: "+loginErrorMessage);
    110.         } else {
    111.             Debug.Log("UDP ok");
    112.             SetupRoom("Sunna");
    113.         }
    114.     }
    115.    
    116.     void OnLogout(BaseEvent evt) {
    117.         smartFox.Disconnect();
    118.     }
    119.    
    120.     public void OnDebugMessage(BaseEvent evt) {
    121.         string message = (string)evt.Params["message"];
    122.         Debug.Log("[SFS DEBUG] " + message);
    123.     }
    124.  
    125.     public void OnJoinRoom(BaseEvent evt)
    126.     {
    127.         Room room = (Room)evt.Params["room"];
    128.         // If we joined a game room, then we either created it (and auto joined) or manually selected a game to join
    129.         if (room.IsGame) {
    130.             Debug.Log ("Joined game room " + room.Name);
    131.             UnregisterSFSSceneCallbacks();
    132.             Application.LoadLevel("game");
    133.         }
    134.     }
    135.  
    136.     public void OnCreateRoomError(BaseEvent evt) {
    137.         string error = (string)evt.Params["errorMessage"];
    138.         Debug.Log("Room creation error; the following error occurred: " + error);
    139.     }
    140.  
    141.     public void OnUserEnterRoom(BaseEvent evt) {
    142.         User user = (User)evt.Params["user"];
    143.         lock (messagesLocker) {
    144.             messages.Add(user.Name + " joined room");
    145.         }
    146.     }
    147.  
    148.     private void OnUserLeaveRoom(BaseEvent evt) {
    149.         User user = (User)evt.Params["user"];
    150.         lock (messagesLocker) {
    151.             messages.Add(user.Name + " left room");
    152.         }
    153.     }
    154.  
    155.     public void OnRoomAdded(BaseEvent evt) {
    156.         Room room = (Room)evt.Params["room"];
    157.         if ( room.IsGame ) {
    158.             smartFox.Send(new JoinRoomRequest("Sunna", null, smartFox.LastJoinedRoom.Id));
    159.         }
    160.     }
    161.    
    162.     public void OnUserCountChange(BaseEvent evt) {
    163.         Room room = (Room)evt.Params["room"];
    164.         if (room.IsGame ) {
    165.         }
    166.     }
    167.  
    168.     public void OnRoomDeleted(BaseEvent evt) {
    169.     }
    170.  
    171.     void OnPublicMessage(BaseEvent evt) {
    172.         try {
    173.             string message = (string)evt.Params["message"];
    174.             User sender = (User)evt.Params["sender"];
    175.    
    176.             lock (messagesLocker) {
    177.                 messages.Add(sender.Name + " said " + message);
    178.             }
    179.            
    180.             Debug.Log("User " + sender.Name + " said: " + message);
    181.         }
    182.         catch (Exception ex) {
    183.             Debug.Log("Exception handling public message: "+ex.Message+ex.StackTrace);
    184.         }
    185.     }
    186.  
    187.     #endregion Callbacks
    188.    
    189.    
    190.  
    191.     private bool isConnected;
    192.    
    193.     void OnGUI()
    194.     {
    195.         if (smartFox == null){
    196.             return;
    197.         }
    198.    
    199.         GUI.DrawTexture(new Rect(0,0,Screen.width,Screen.height), background);
    200.         GUI.skin = gSkin;
    201.        
    202.         int ScreenX = ((int)(Screen.width / 2) - (areaWidth / 2));
    203.         int ScreenY = ((int)(Screen.height / 2) - (areaHeight / 2));
    204.  
    205.         // Connect
    206.         if (!isConnected) {
    207.             GUILayout.BeginArea (new Rect (ScreenX, ScreenY, areaWidth, areaHeight),"Login","Window");
    208.             GUILayout.Label("Server: ");
    209.             serverName = GUILayout.TextField(serverName, 25);
    210.  
    211.             GUILayout.Label("Port: ");
    212.             serverPort = int.Parse(GUILayout.TextField(serverPort.ToString(), 4));
    213.            
    214.             GUILayout.Label( "Username: ");
    215.             username = GUILayout.TextField( username, 25);
    216.            
    217.             GUILayout.Label("Password: ");
    218.             userpassword=GUILayout.PasswordField (userpassword, "*"[0], 25);
    219.            
    220.             GUILayout.Space(4);
    221.             if (GUILayout.Button("Login")  || (Event.current.type == EventType.keyDown  Event.current.character == '\n'))
    222.             {
    223.                 AddEventListeners();
    224.                 smartFox.Connect(serverName, serverPort);
    225.             }
    226.             GUILayout.EndArea();
    227.         }
    228.     }
    229.    
    230.     private void SetupRoom(string roomName){
    231.         if(smartFox.GetRoomByName(roomName)==null){
    232.            
    233.             RoomSettings settings = new RoomSettings(roomName);
    234.             settings.GroupId = "game";
    235.             settings.IsGame = true;
    236.             settings.MaxSpectators = 0;
    237.             settings.Extension = new RoomExtension(NetworkManager.ExtName, NetworkManager.ExtClass);
    238.             smartFox.Send(new CreateRoomRequest(settings, true, smartFox.LastJoinedRoom));
    239.         }else{
    240.             smartFox.Send(new JoinRoomRequest(roomName));
    241.         }
    242.     }
    243.    
    244.      void OnApplicationQuit() {
    245.         if (smartFox.IsConnected) {
    246.             smartFox.Disconnect();
    247.         }
    248.     }
    249. }
    It should look like this:


    3. Handling Information between Server and Client
    I want to show this based on my InventorySystem(it is not completely done but i will Update this small tutorial)

    In the NetworkManager.cs i have added this code for picking up an item.
    Code (csharp):
    1.         /// <summary>
    2.     /// Request for collecting Items
    3.     /// </summary> 
    4.     public void PickUpRequest(int id,string name){
    5.         Room room = smartFox.LastJoinedRoom;
    6.         ISFSObject data=new SFSObject();
    7.         data.PutInt("id",id);
    8.         data.PutUtfString("name",name);
    9.         ExtensionRequest request = new ExtensionRequest("pickUp", data, room);// *1
    10.         smartFox.Send(request);
    11.     }
    1* //<--- this message with some data will be sended to the server. I have put the id and the name of the item to the data, but you can put in it what you like. Later the item will be checked(is this item movable, is my cmdLevel high enough for picking it up, and get its data like damage or quality from a database...) based on this data.

    Now i have created a new c# script called ItemController.cs and put this script on every GameObject which can be picked up. Read the code to know what it does.
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ItemController : MonoBehaviour {
    5.     public Texture2D inventoryIcon;
    6.     public int id; // the id should be generated, but for testing it is good enough
    7.  
    8.     // Use this for initialization
    9.     void Awake () {
    10.         gameObject.name = gameObject.name.Replace("(Clone)",""); //The name of the gameobject will be replaced i delete the "Clone".
    11.     }
    12.    
    13.         //If the player clicks on the gameobject we will send the request to pickup the item.
    14.     void OnMouseUp(){
    15.         NetworkManager.Instance.PickUpRequest(id ,gameObject.name);
    16.     }
    17. }
    Now we need something on the server, what can get this request, do the checks and send an "ok" to the client. I am using eclipse to write the server code.

    You can download it here.

    Maybe i have to explain first the setup eclipse with the example FPS Demo:

    - if You have installed eclipse, create a new workspace.
    - click with the right-mouse-button to import a new project.


    - now import an existing project



    - click on next and brows the "SFS2XFPSextension" folder and the finish button
    - it should look like this:


    Now you have done the setup and can start with coding.

    Add a new Requesthandler to your FPSExtension. I have renamed them so it looks diffrent.




    Code (csharp):
    1. @Override
    2.     public void init() {
    3.         world = new World(this);  // Creating the world model
    4.  
    5.         // Subscribing the request handlers
    6.         addRequestHandler("sendTransform", SendTransformHandler.class);
    7.         addRequestHandler("sendAnim", SendAnimHandler.class);
    8.         addRequestHandler("spawnMe", SpawnMeHandler.class);
    9.         addRequestHandler("getTime", GetTimeHandler.class);
    10.         addRequestHandler("pickUp",PickUpHandler.class);
    11.         addRequestHandler("getInventoryList",InventoryHandler.class);
    12.        
    13.         addEventHandler(SFSEventType.USER_DISCONNECT, OnUserGoneHandler.class);
    14.         addEventHandler(SFSEventType.USER_LEAVE_ROOM, OnUserGoneHandler.class);
    15.         addEventHandler(SFSEventType.USER_LOGOUT, OnUserGoneHandler.class);
    16.  
    17.         trace("FPS extension initialized");
    18.     }
    - Create a new java class and call it "PickUpHandler".

    Code (csharp):
    1. public class PickUpHandler extends BaseClientRequestHandler{
    2.    
    3.     @Override
    4.     public void handleClientRequest(User user, ISFSObject data) {
    5.         World world = RoomHelper.getWorld(this);
    6.         SigCharacter player=world.getPlayer(user);
    7.         //Login to database and get item data
    8.         //---
    9.         SigItem item= new SigItem(data.getInt("id"),data.getUtfString("name"),new Transform(0,0,0,0,0,0),124);
    10.         //---
    11.         player.AddItem(item);
    12.         world.useItem(player, item);
    13.     }
    14. }
    Now you can get the information of the item you have sended. The information is in the ISFSObject data .
    You can get the id :

    data.getInt("id")

    then log in to a database and pick the item and send the whole information of the item to the client.

    (I am a hobby programmer so i do not know if this is the best method.)
    - then you can add this item to a List and you have got your inventory List.
    - now you can code a request to get the inventory List the same way.

    Add a Request in the NetworkManager.cs
    Code (csharp):
    1.     /// <summary>
    2.     /// Request for the InventoryList
    3.     /// </summary> 
    4.     public void InventoryRequest(){
    5.         Room room = smartFox.LastJoinedRoom;
    6.         ExtensionRequest request = new ExtensionRequest("getInventoryList", new SFSObject(), room);
    7.         smartFox.Send(request);
    8.     }
    Send Request to the server

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class InputHandler : MonoBehaviour {
    5.    
    6.     void Update () {
    7.         // I: Inventory
    8.         if (Input.GetKeyUp(KeyCode.I))
    9.         {
    10.            NetworkManager.Instance.InventoryRequest();
    11.         }
    12.        
    13.     }
    14. }
     
    Last edited: Jan 23, 2012
  2. surfy1h

    surfy1h

    Joined:
    Nov 23, 2010
    Posts:
    16
    thanks Zerano
     
  3. DevionGames

    DevionGames

    Joined:
    Feb 22, 2010
    Posts:
    1,624
    No Problem, it is good to read a thanks, because of no reply i thought nobody needs a tutorial like this and i wanted to stop it :D
     
  4. sandolkakos

    sandolkakos

    Joined:
    Jun 3, 2009
    Posts:
    267
    Thanks for your dedication to write this tutorial., Zerano.
     
  5. LucasDaltro

    LucasDaltro

    Joined:
    Oct 31, 2010
    Posts:
    236
    OMG!!!This tutorial appears exactly in the hour that I most need it:DThank you buddy thanks very much:D
     
  6. 95KillerZ95

    95KillerZ95

    Joined:
    May 27, 2011
    Posts:
    253
    Nice, very useful tutorial :D
     
  7. DevionGames

    DevionGames

    Joined:
    Feb 22, 2010
    Posts:
    1,624
    some new basic information...
     
  8. DevionGames

    DevionGames

    Joined:
    Feb 22, 2010
    Posts:
    1,624
  9. Andman

    Andman

    Joined:
    Jun 28, 2011
    Posts:
    4
    Nice Zerano !


    Thumbs up
     
  10. Nemodain

    Nemodain

    Joined:
    Mar 21, 2009
    Posts:
    5
    Thank you very much Zerano, this is a very wonderful tutorial. This and your work on the RPG starter kit have kept me very busy.

    Keep up the good work!


    Nemo
     
  11. mtewks

    mtewks

    Joined:
    Jun 10, 2011
    Posts:
    82
    - in the folder SFS2x you will find a new folder with the name extensions open the folder and put in it the folder from the FPS Demo called SFS2XFPSextension

    What folder from what FPS Demo?
    Your asking me to put the SFS2XFPSextension in the SFS2XFPSextension? What?
    There was only UnityFPSDemo and two folders SFS2XFPSextension and SFS2XFPSTutorial.
    So, I'm very confused by this step.

    EDIT: I finally got what you mean, but what's that last step with inputhandler?
    No such script in Unity project I have
     
    Last edited: Jul 27, 2011
  12. CuddleBeaver

    CuddleBeaver

    Joined:
    Aug 6, 2011
    Posts:
    1
    Thank you very much for this tutorial - this is exactly what I needed plus bonus stuff like the change of the login GUI. I'd better check out what else you've made (¨,)


    /Jens
     
  13. chrisx84

    chrisx84

    Joined:
    Nov 9, 2011
    Posts:
    85
    sorry to be a downer but I'm running into alot of errors with just LobbyGUI.cs
    Its complaining about ArrayList on line 24 and SmartFoxConnection.IsInitialized on line 31 of LobbyGUI.cs and thats just the beginning, im now scared to strip the coding to find any more errors.