1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. GTA Network forum is now in archive mode.

Simple CEF Tutorial

Discussion in 'Tutorials/Documentations' started by TakeiT, Jan 28, 2017.

  1. TakeiT

    TakeiT Member

    Messages:
    40
    Likes Received:
    15
    Joined:
    Dec 28, 2016
    I've noticed that there's been a lot of questions asked about using CEF, as the wiki is not all that clear. In this thread, we will make a simple login form, and then pass the data into the server.

    First of all, The Chromium Embedded Framework (CEF) is an open source framework for embedding a web browser engine based on the Chromium core. It is a convenient way to add web browser control and implement an HTML5-based layout GUI in a desktop application or to provide web browser capabilities to a software application or game, and provides the infrastructure developers need to quickly add HTML rendering and JavaScript to a C++ project. (Credit to Wikipedia).

    Essentially, CEF is an HTML viewer in game. This means we can use HTML to create various features, such as menus, forms and more.

    1. Meta File: As you should already know, each resource has a meta.xml file. Every file that your CEF browser uses (All HTML files, JS includes, CSS, images etc) must be included, or they will not show up in game. They are included like this:
      Code:
      <file src="filename.extension" />
    2. Javascript: CEF is enabled by using client sided JS files. In your favorite editor, create a new file called cef.js.
    3. Declaring the variable: We need to declare a variable to identify the browser. This will be used to open, set values and close the browser. On the first line, enter the following:
      Code:
      var myBrowser = null; //we set it to null because the browser is not yet created, we cannot have a var that has empty value, so we use null
    4. Creating the browser: Depending on what you're doing will depend on where the browser is created. We are going to put this under onResourceStart, so that it shows when the player connects to the server. We need to enter the following code:
      Code:
      API.onResourceStart.connect(function()
      {
      
          var res = API.getScreenResolution(); //this gets the client's screen resoulution
          myBrowser= API.createCefBrowser(res.Width, res.Height); //we're initializing the browser here. This will be the full size of the user's screen.
          API.waitUntilCefBrowserInit(myBrowser); //this stops the script from getting ahead of itself, it essentially pauses until the browser is initialized
          API.setCefBrowserPosition(myBrowser, 0, 0); //The orientation (top left) corner in relation to the user's screen.  This is useful if you do not want a full page browser.  0,0 is will lock the top left corner of the browser to the top left of the screen.
          API.loadPageCefBrowser(myBrowser, "myfile.html"); //This loads the HTML file of your choice.      .    API.setCefBrowserHeadless(myBrowser, true); //this will remove the scroll bars from the bottom/right side
          API.showCursor(true); //This will show the mouse cursor
          API.setCanOpenChat(false);  //This disables the chat, so the user can type in a form without opening the chat and causing issues.
      });
    5. Creating the HTML File: Next, we need to create the html file that will actually be shown. Create a new HTML file and enter the following:

      Code:
       <!-- just a basic HTML file, go as advanced as you like -->
      <html>
          <form>
            <input type="text" id="username" placeholder="username"/>
            <input type="password" id="password" placeholder="password"/>
            <button onclick="logPlayer();" id="login">login</button> <!--note the "onclick", this will be used in the next step__>
          </form>
      
      </html>
      
    6. Getting the values: Next, we need to get the values of username and password when login is pressed. This can be done with javascript. Just above the <html> tag, create a new script.
      Code:
      <script>
      	function logPlayer()  //this is the function we called with OnClick in the last step
      	{
      		var username = $("#username").val(); //set a var "username" to the value of the input with the id "username"
      		var password = $("#password").val();//set a var "password" to the value of the input with the id "password"
      		resourceCall("login", username, password); //call a function named "login" in our javascript file.
      	};
      
      </script>
      
    7. Wiring it up: Save and close that html file. Go back to your JS file we opened the CEF browser in. We now need to create our login function that we called in the html script. Note that we will not be hooking this to a database and making the login features actually work, this is simply a demonstration of CEF. Create the following:
      Code:
      function login(Username, Password)
      {
          API.sendChatMessage("Your username is " + Username + " and your password is " + Password); //send a chat message with the data they entered.
          API.showCursor(false); //stop showing the cursor
          API.destroyCefBrowser(myBrowser); //destroy the CEF browser
          API.setCanOpenChat(true); //allow the player to use the chat again.
      }
      

    And that's all there is to it! A simple CEF browser. I hope I answered some questions you might have had.
     
    rum, ATomas, EN3RGGY and 3 others like this.
  2. andreasb

    andreasb Well-Known Member

    Messages:
    128
    Likes Received:
    61
    Joined:
    Aug 4, 2016
    This'll definitely help out for quite a few!
    Initial feedback: You're using jQuery to get the values of the username and password input fields. However, you're not mentioning or importing jQuery anywhere (or including it in your meta.xml). Perhaps showcasing a pure/library-free implementation would be better :=). And I'd consider it quite unusual to have script tags outside of your <html> (it's also invalid html). It's common to have it either at the bottom of the <body> tag or inside your <head> tag.
     
    Last edited: Jan 28, 2017
    Bruno likes this.
  3. TakeiT

    TakeiT Member

    Messages:
    40
    Likes Received:
    15
    Joined:
    Dec 28, 2016
    The reason why I had it outside of the HTML tag is because the function wouldn't work in game with it in the html tags, though it would work in the browser. I forgot the jquery, will update, thanks
     
  4. Kieron Wiltshire

    Kieron Wiltshire Member

    Messages:
    8
    Likes Received:
    1
    Joined:
    Feb 6, 2017
    Is it possible to create client specific content? For example if I wanted to create a character viewer and I was getting these from the database and passing them to the client, could I open up a UI with a HTML page containing the characters names in?

    Basically I'm asking if it's possible to create dynamic content?
     
  5. KnowN

    KnowN Member

    Messages:
    14
    Likes Received:
    2
    Joined:
    Feb 6, 2017
    Very useful bro, good work.
     
  6. TakeiT

    TakeiT Member

    Messages:
    40
    Likes Received:
    15
    Joined:
    Dec 28, 2016
    You should be able to do that using resourceCall. Create a JQuery function to get the information and return it as a string.
     
  7. Kieron Wiltshire

    Kieron Wiltshire Member

    Messages:
    8
    Likes Received:
    1
    Joined:
    Feb 6, 2017
    I mean the other way around ...
    Rendering HTML specific to a user.
     
  8. Tosfera

    Tosfera New Member

    Messages:
    3
    Likes Received:
    0
    Joined:
    Mar 9, 2017
    You can use myBrowser.call (or what ever your Browser variable is). Example;

    Code:
    myBrowser.call ("fillUserTable", username);
     
  9. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    I have followed the instructions, but to create a white box with no content (rear input). What did I do wrong?

    In: C:\GTANetwork\resources\my_script
    is exists .js file
    but not exists .html file

    In server i have both of files (.js and .html) in folder.

    Thanks for help
     
  10. Draex

    Draex Active Member

    Messages:
    64
    Likes Received:
    31
    Joined:
    Apr 2, 2017
    Check your meta.xml file, you have to add your html documents like this:
    <file src="client/resources/main.html" />

    For the people using call and resourceCall, it seems like, as if it's neither possible to use one of this functions with javascript objects as parameters, nor to use them with js arrays (as far as I've tested it and I've tested a lot). Also I noticed some strange behavior if you're using a float value as argument for call, so also be aware of that.

    A possible workaround for arrays should be to create a function that takes a key as one argument and a value as second one. Then in your (client side) script you iterate through the array using javascripts forEach (not jQuery!) and make a call like browser.call("func", key, value) for each element. Also take care that your browser is done with loading, won't work otherwise.

    I've implemented that stuff, but in a a little bit more complex way as I described it here, it's working.
     
    WarrioR™ and ATomas like this.
  11. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    Thank you, this resolve my problem, but i have another problem. When i write something in input box and click "Login" no happened, no error no message. Only in log C:\GTANetwork\logs

    -> [Local mode] Uri: http://aaa/test.html?
    -> Loading: C:\GTANetwork\resources\aaa\test.html
    Closed file stream!
    -> Setting main context!
    -> Main context set!
    -> Start: http://aaa/test.html?
    -> End: http://aaa/test.html?, 200

    I use this:

    function logPlayer() //this is the function we called with OnClick in the last step
    {
    alert("ok");
    var username = $("#username").val(); //set a var "username" to the value of the input with the id "username"
    var password = $("#password").val();//set a var "password" to the value of the input with the id "password"
    alert("ok2");
    resourceCall("login", username, password); //call a function named "login" in our javascript file.
    alert("nick " + username + " heslo " + password);
    };

    alert "OK" is show, but alert "OK2" not


    Thanks for help
     
    Last edited: Apr 5, 2017
  12. Draex

    Draex Active Member

    Messages:
    64
    Likes Received:
    31
    Joined:
    Apr 2, 2017
    You should check if jQuery is loaded properly, I think you can just go for something like alert($), if it says "undefined" you got a problem with jQuery
     
  13. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    You're right, jQuery does not work.

    This is better:

    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;

    But its problem, how to send username and password to server ?

    API.call("aaa", "PlayerLogin", Username, Password);
    API.triggerServerEvent("PlayerLogin", Username, Password);

    does not work
     
  14. Draex

    Draex Active Member

    Messages:
    64
    Likes Received:
    31
    Joined:
    Apr 2, 2017
    The API object is not available in the cef (and cannot be passed through functions), but you can use resourceCall instead (like in step 7 of the tutorial)
     
  15. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    I have this (.js file):
    Code:
    var myBrowser = null;
    
    API.onResourceStart.connect(function()
    {
        var res = API.getScreenResolution(); //this gets the client's screen resoulution
        myBrowser= API.createCefBrowser(res.Width/2, res.Height/2); //we're initializing the browser here. This will be the full size of the user's screen.
        API.waitUntilCefBrowserInit(myBrowser); //this stops the script from getting ahead of itself, it essentially pauses until the browser is initialized
        API.setCefBrowserPosition(myBrowser, 0, 0); //The orientation (top left) corner in relation to the user's screen.  This is useful if you do not want a full page browser.  0,0 is will lock the top left corner of the browser to the top left of the screen.
        API.loadPageCefBrowser(myBrowser, "test.html"); //This loads the HTML file of your choice.      .    API.setCefBrowserHeadless(myBrowser, true); //this will remove the scroll bars from the bottom/right side
        API.showCursor(true); //This will show the mouse cursor
        API.setCanOpenChat(false);  //This disables the chat, so the user can type in a form without opening the chat and causing issues.
    });
    
    function login(Username, Password)
    {
        API.sendChatMessage("Your username is " + Username + " and your password is " + Password); //send a chat message with the data they entered.
        API.showCursor(false); //stop showing the cursor
        API.destroyCefBrowser(myBrowser); //destroy the CEF browser
        API.setCanOpenChat(true); //allow the player to use the chat again.
    
        API.call("aaa", "PlayerLogin", Username, Password);
        API.triggerServerEvent("PlayerLogin", Username, Password);
    }
    .html file
    Code:
    <html>
        <form>
          <input type="text" id="username" placeholder="username"/>
          <input type="password" id="password" placeholder="password"/>
          <button onclick="logPlayer();" id="login">login</button>
        </form>
    
    </html>
    
    <script>
        function logPlayer()  //this is the function we called with OnClick in the last step
        {
            var username = document.getElementById("username").value;//= $("#username").val(); //set a var "username" to the value of the input with the id "username"
            var password = document.getElementById("password").value;//= $("#password").val();//set a var "password" to the value of the input with the id "password"
            resourceCall("login", username, password); //call a function named "login" in our javascript file.
            //alert("nick " + username + " heslo " + password);
        };
    </script>
    and .cs code
    Code:
    public void PlayerLogin(string username, string password)
        {
            API.consoleOutput("1)Hráč " + username + "se prihlásil s heslem " + password);
        }
    
        public void onClientEventTrigger(Client player, string eventName, params object[] args)
        {
            if(eventName == "PlayerLogin")
            {
                API.consoleOutput("2)Hráč " + args[0].ToString() + "se prihlásil s heslem " + args[1].ToString());
            }
        }
     
  16. Draex

    Draex Active Member

    Messages:
    64
    Likes Received:
    31
    Joined:
    Apr 2, 2017
    Your code can not workout like that (many problems there), you should wait for a detailed cef tutorial.
    Correct interaction with the cef is one of the most complicated things to do in gta:n.
    Maybe I put some code on pastebin or in a seperate thread, because I think this is not the right place to explain the entire cef/script interaction
     
  17. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    I read this tutorial: https://forum.gtanet.work/index.php?threads/send-data-between-server-and-client.265/

    Why does it not work? Transferring data from client to server, no need CEF.
     
  18. ATomas

    ATomas Active Member

    Messages:
    61
    Likes Received:
    1
    Joined:
    Apr 4, 2017
    I solved the problem:
    onClientEventTrigger renamed to OnClientEvent and add in main API.onClientEventTrigger += OnClientEvent; and its works
     
  19. Culvanen

    Culvanen Member

    Messages:
    32
    Likes Received:
    2
    Joined:
    Apr 15, 2017
    Hi, i have follow multiple tutorial for make a simple login page in html in main screen on my server at connexion but its not working at all

    can you help me with simple explanations (for beginners)

    Thanks
     
  20. Draex

    Draex Active Member

    Messages:
    64
    Likes Received:
    31
    Joined:
    Apr 2, 2017
    Some details would be great :=D
    Go post the content of your GTA:N logs (C:\GTANetwork\logs, CEF.txt & Error.txt)
     

Share This Page