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.

Transfer a list with objects from your server to your client.

Discussion in 'Tutorials/Documentations' started by Roel, Jan 25, 2017.

  1. Roel

    Roel Member

    Messages:
    26
    Likes Received:
    11
    Joined:
    Sep 14, 2016
    Hello,

    I want to share a way to transfer many objects of any kind from server to client.
    First of all you need a little knowledge about C# And Javascript/jQuery.

    Lets use an inventory script as example, we are going to send a list of a custom object 'Item' to the client and render them inside a html file.

    Before we can start you need to add a reference called 'System.Web.Extensions'.

    Add
    Code:
    using System.Web.Script.Serialization;
    At the top of your script.

    Now we can start with the server-side script:

    Code:
        public void OnClientEvent(Client player, string eventName, params object[] arguments)
        {
            if (eventName == "LoadInventory")
            {
                List<Item> items = new List<Item>();
                items.Add(new Item(1, "Infection", 4, "3"));
                items.Add(new Item(2, "Gasmask", 1, "5"));
                items.Add(new Item(3, "Rope", 1, "6"));
                items.Add(new Item(4, "Gloves", 2, "8"));
                items.Add(new Item(5, "Hook", 4, "9"));
                items.Add(new Item(6, "Fire", 6, "22"));
                items.Add(new Item(6, "Gasoline", 3, "20"));
    
                var jsonSerialiser = new JavaScriptSerializer();
                var json = jsonSerialiser.Serialize(items);
    
                API.triggerClientEvent(player, "InventoryItems", json);
            }
        }
    
    This event will be called from our html file when it's loaded in a CEF Browser,
    when all items are generated it will trigger an event at the client-side.

    Now we go to the client script:

    Code:
    API.onServerEventTrigger.connect(function (eventName, args) {
        switch (eventName) {
            case 'InventoryItems':
                if(cefInventory.open)
                {
                    cefInventory.browser.call("LoadItems", args[0]);
                }
                break;
        }
    });
    
    function LoadInventory() {
        API.triggerServerEvent("LoadInventory");
    }
    
    
    This event will be called by the server that we made at the previous step.
    cefInventory.browser is my CEF browser, you will need to replace this with your own browser.


    Now inside our HTML file we are going to display the recieved items:

    Code:
    <script>
        $( document ).ready(function() {
            resourceCall("LoadInventory");
        });
    
        function LoadItems(itemsjson) {
            var items = jQuery.parseJSON(itemsjson);
            var html = "";
            for (var i = 0; i < items.length; i++) {
                html = html + '<div class="col-md-1 inv-item"><img src="../Assets/img/items/' + items[i].Image + '.png" alt="" class="img-rounded"><span class="inv-label">' + items[i].Name + '</span><span class="inv-amount">' + items[i].Amount + 'x</span></div>';
            }
            $(".inv-row").html(html);
        }
    </script>
    
    
    As you can see I used jQuery, you can also do it without jQuery.
    So when my document is ready it calls LoadInventory() which is located in my client script.
    Then my client script returns the items that it recieved from my server script.
    Inside LoadItems the items are parsed to a JSON object, next I loop through them and display them.

    And here is my result:
    [​IMG]

    I hope this script can be useful for people, have questions? Ask them!
    Maybe I release the full resource in a while.
     
    StreetGT, Hazes, Mendes and 2 others like this.
  2. Nildius

    Nildius Member

    Messages:
    13
    Likes Received:
    0
    Joined:
    Sep 30, 2016
    Greaaaat! Thanks for share that!

    How can i load a big number of icons in meta.xml? I dont want to put one by one <file src="icon1.png"> <file src="icon2.png">. Is there any way to load it dynamically?
     
    Last edited: Jan 25, 2017
  3. Roel

    Roel Member

    Messages:
    26
    Likes Received:
    11
    Joined:
    Sep 14, 2016
  4. Widying

    Widying Member

    Messages:
    8
    Likes Received:
    0
    Joined:
    Jan 7, 2017
    is error at "Item" in

    Code:
    List<Item> items = new List<Item>();
    items.Add(new Item(1, "Infection", 4, "3"));
    items.Add(new Item(2, "Gasmask", 1, "5"));
    items.Add(new Item(3, "Rope", 1, "6"));
    items.Add(new Item(4, "Gloves", 2, "8"));
    items.Add(new Item(5, "Hook", 4, "9"));
    items.Add(new Item(6, "Fire", 6, "22"));
    items.Add(new Item(6, "Gasoline", 3, "20"));
     
  5. Roel

    Roel Member

    Messages:
    26
    Likes Received:
    11
    Joined:
    Sep 14, 2016
    Ye you cant just copy and paste this code, it's a tutorial, the Object Item is a custom object of mine.
    You will have to create or insert your own objects to this list.
     
  6. Hazes

    Hazes Active Member

    Messages:
    95
    Likes Received:
    21
    Joined:
    Apr 8, 2017
    Hey man. I'm trying to receive a json array inside client .js file. But I'm getting hundreds of serverside errors at time:

    [12:05:10] System.ArgumentException: Maximum depth RecursionLimit exceeded.
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat)
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)
    w System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)
    w System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat)
    w System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat)
    w Licence.InitializeDrivingTest(Client player, String category)
    w Licence.OnClientLicenceEventHandler(Client player, String eventName, Object[] args)
    w GTANetworkServer.ScriptingEngine.<>c__DisplayClass59_0.<InvokeClientEvent>b__0()
    w GTANetworkServer.ScriptingEngine.MainThreadLoop()

    And the code is:

    Code:
            List<LicenceWaypoint> route = new List<LicenceWaypoint>();
            foreach(LicenceWaypoint waypoint in LicenceWaypoint.Route)
            {
                if(waypoint.id == 0)
                {
                    route.Add(waypoint);
                }
            }
    
            var jsonSerialiser = new JavaScriptSerializer();
            var json = jsonSerialiser.Serialize(route);
    
            API.triggerClientEvent(player, "LOAD_DRIVINGTEST_ROUTE", json);
    Can you tell me what am I doing wrong? :=)
    Great tutorial! Just what I was looking for. ;-)

    // EDIT :
    Got it working now. Used Newtonsoft Json instead of Web Extensions.
     
    Last edited: Jul 19, 2017

Share This Page