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.

How to Build an Effective OOP User System with agrSQL

Discussion in 'Tutorials/Documentations' started by AgresivD, Mar 25, 2017.

  1. AgresivD

    AgresivD Member

    Messages:
    8
    Likes Received:
    14
    Joined:
    Jan 12, 2017
    How to Build an Effective OOP User System
    using agrSQL - SQL class allows to handle the MySQL database.
    Introduction
    In this tutorial I will teach you to create an advanced and efficient user system using OOP programming.
    We will also use the agrSQL I developed for our work to be much more convenient.
    This system is different from the other user systems published here in the forum, if you understand the technique of this system you can program any system in a very advanced and effective, enjoyable reading and success!


    What is OOP?
    Object-oriented programming is actually imitating human thinking. When we look at the world we naturally classify all the objects and concepts by categories. For example, the world is divided into living, flora and still. The animals are classified into mammals, poultry and fish. The birds are again classified into additional categories. Hence every object or concept we think about is found in many categories. This classification by categories / sub-concepts helps us to control and arrange the vast information we deal with. For example - if we want to describe something to a certain model of a car - we should describe only the features that distinguish the same model but do not need to add that the car has four wheels, Engine, trunk, steering wheel, etc. Since we sorted the object - in this case - from a car, to a certain type, we avoided mentioning all the trivial features of the car.
    Object-oriented software development is the accepted and popular approach in the software world.

    How It Works?
    [​IMG]

    Setup SQL Settings:
    First we need to create the table where we store our user information.
    These are the fields I have selected for this tutorial, you can also expand them.

    PHP:
    CREATE TABLE `Users` (
      `
    IDint(11NOT NULL,
      `
    Usernametext NOT NULL,
      `
    Passwordtext NOT NULL,
      `
    Createdint(11NOT NULL,
      `
    Killsint(11NOT NULL
    ENGINE=MyISAM DEFAULT CHARSET=latin1;

    ALTER TABLE `Users`
      
    ADD PRIMARY KEY (`ID`);
    ALTER TABLE `Users`
      
    MODIFY `IDint(11NOT NULL AUTO_INCREMENT;
    After we have defined our table (you can also do that with phpMyAdmin) or send it to the as query to database. Now we need to create connection between database to are resource, First you need define agrSQL object somewhare in your code:
    PHP:
    public static agrSQL sqlLink = new agrSQL();
    After you do that you ready to use all agrSQL functions,
    This code line ^ are not create that connection we talked about. agrSQL have function names Connect And she does it:
    PHP:
    sqlLink.Connect("server""database""user""password");
    The connection should be at the time the resource is loaded and therefore we will insert this line in OnResourceStart.

    Defining the classes:
    In our user system, we will define 2 main classes:
    PHP:
    /// <summary>
    /// UsersTypes class provides properties for Users element.
    /// </summary>
    public class UsersTypes
    {
    }
    /// <summary>
    /// Users class allows to handle the users system; add new, list all, etc.
    /// </summary>
    public class Users UsersTypes
    {
    }

    Defining the Accounts list:
    This list contains all users objects.
    PHP:
    public class Lists
    {
        public static List<
    UsersAccounts = new List<Users>();
    }

    Define UsersTypes class:
    In this section we will define the settings of our user system.
    We will adjust our variables to the table we created in the first step of the tutorial.
    PHP:
    public class UsersTypes
    {
        public 
    int ID 0,
            
    Kills 0;
        public 
    String Username String.Empty,
            
    Password String.Empty;
        public 
    DateTime Created = default(DateTime);
    }
    These are the settings each user will receive. Number of kills, registration date and more..
    After reading this guide you can expand the system and add additional settings to UsersTypes.


    Define Users class:
    Our Users class is divided into three parts:
    [​IMG]

     
    Last edited: Mar 25, 2017
    Gonzov, Amit_B, Toro and 1 other person like this.
  2. AgresivD

    AgresivD Member

    Messages:
    8
    Likes Received:
    14
    Joined:
    Jan 12, 2017
    Create Users Constructors:
    We need to create 2 constructors.
    PHP:
    /// <summary>
    /// Construct a new user object with default properties in order to add it to the database.
    /// </summary>
    public Users(String nicknameString passwd)
    {
        
    Username nickname;
        
    Password passwd;
        
    Created DateTime.Now;
    }

    /// <summary>
    /// Construct a new user object in order to load its properties from an existing user in the database.
    /// </summary>
    public Users(int uidString nicknameString passwdDateTime registerdateint kills)
    {
        
    ID uid;
        
    Username nickname;
        
    Password passwd;
        
    Kills kills;
        
    Created registerdate;
    }

    Create Users Static Functions:
    There is a single static function we called the name Load.
    You can probably guess what the purpose of this function (Load all users from database to Accounts list) is and when it works (called from OnResourceStart)
    PHP:
    public static short Load()
    {
        
    Lists.Accounts.Clear();
        
    DataSet dsResVar = new DataSet();
        
    string table "Users";
        
    sqlLink.ReadTable(ref dsResVartableString.Empty, "ID,Username,Password,Kills,Created");
        for(
    int i 0sqlLink.Count(table); ki++)
        {
            
    Users tmpUser = new Users(
                (int)
    dsResVar.Tables[table].Rows[i]["ID"],
                
    dsResVar.Tables[table].Rows[i]["Username"].ToString(),
                
    dsResVar.Tables[table].Rows[i]["Password"].ToString(),
                (int)
    dsResVar.Tables[table].Rows[i]["Kills"],
                
    DateTimeFromUnixTime((int)dsResVar.Tables[table].Rows[i]["Created"]));
            
    Lists.Accounts.Add(tmpUser);
        }
        return (
    short)Lists.Accounts.Count;
    }

    DateTimeFromUnixTime - this function Gets an int value representing unixtime and converts it to the DateTime type, This is how it is defined in the code:
    PHP:
    public static DateTime DateTimeFromUnixTime(int unixtime)
    {
        
    DateTime dtDateTime = new DateTime(1970110000DateTimeKind.Utc);
        
    dtDateTime dtDateTime.AddSeconds(unixtime).ToLocalTime();
        return 
    dtDateTime;
    }
    Create Users Internal Functions:
    Now we need to create 2 internal functions called Add, Update.
    We start with Add function:
    PHP:
    public int Add()
    {
        
    sqlLink.Insert("Users",
            new 
    KeyValuePair<stringobject>("Username"Username),
            new 
    KeyValuePair<stringobject>("Password"Password),
            new 
    KeyValuePair<stringobject>("Kills"Kills),
            new 
    KeyValuePair<stringobject>("Created"UnixTimeFromDateTime(Created)));
        
    Lists.Accounts.Add(this);
        
    ID Lists.Accounts.Count;
        return 
    ID;
    }
    Add function create new field in table "Users" and insert all UsersTypes values According to the class, we see in this code new function called UnixTimeFromDateTime This function performs the reverse operation to DateTimeFromUnixTime That we knew in Load ^, This is how it is defined in the code:
    PHP:
    public static int UnixTimeFromDateTime(DateTime datetime)
    {
        return (int)
    Math.Truncate((datetime.ToUniversalTime().Subtract(new DateTime(197011))).TotalSeconds);
    }
    Now we need to create Update function for update the current values of the class in database,
    Its code is very similar to Add only performs a different action:
    PHP:
    public void Update()
    {
        
    sqlLink.Update("Users""`ID` = '" ID "'",
            new 
    KeyValuePair<stringobject>("Username"Username),
            new 
    KeyValuePair<stringobject>("Password"Password),
            new 
    KeyValuePair<stringobject>("Kills"Kills),
            new 
    KeyValuePair<stringobject>("Created"UnixTimeFromDateTime(Created)));
    }
    When we update Users table we need to know wich field to update, Each user added to the database gets a serial number (ID) We defined this action in the SQL code that creates the Users table in the following rows:
    PHP:
    ALTER TABLE `Users`
      
    ADD PRIMARY KEY (`ID`);
    ALTER TABLE `Users`
      
    MODIFY `IDint(11NOT NULL AUTO_INCREMENT;
    Now when we want to update a user we tell sql in Update function to update the user with the serial number X like we do in Update() function above ^.
     
    Last edited: Mar 25, 2017
    Amit_B, Gonzov and SpectralEye like this.
  3. AgresivD

    AgresivD Member

    Messages:
    8
    Likes Received:
    14
    Joined:
    Jan 12, 2017
    How do we proceed from here?:
    Now our Users class is ready! and now we can use functions in the main code.
    First you need to define static variable that contains UserID That Represents the user's ID in the Accounts list.
    PHP:
    public static int UserID = -1;
    Load all users (API.onResourceStart):
    PHP:
    private void OnResourceLoad()
    {
        
    sqlLink.Connect("host""database""user""password");
        
    int countUsers Users.Load();
        
    API.consoleOutput("Users loaded: {0}"countUsers);
    }
    Check if user exists (API.onPlayerConnected):
    PHP:
    UserID Lists.Accounts.FindIndex(=> i.Username == player.name);
    if(
    UserID != -1)
        
    API.sendChatMessageToPlayer(player"You are already register please login.");
    else
        
    API.sendChatMessageToPlayer(player"You are not registered.");
    Create new user (register command, dialog..):
    PHP:
    Users registerUser = new Users(player.name"password");
    UserID registerUser.Add();
    Update user (API.OnPlayerDisconnected):
    PHP:
    Lists.Accounts[UserID].Update();
    Summary:
    Those who really understood the manual and the tools I gave here can create any system in a very efficient and convenient way. GTANetwork gave us the opportunity to develop in C# and it is important to take advantage of the amazing possibilities that this language gives us.

    - Soon I will post the complete system + amazing update to agrSQL

    Comments :=)
     
    Amit_B and Gonzov like this.
  4. Guy

    Guy Member

    Messages:
    11
    Likes Received:
    0
    Joined:
    Oct 28, 2016
    Awesome! Thank you!
     
  5. arayni

    arayni New Member

    Messages:
    1
    Likes Received:
    0
    Joined:
    Mar 16, 2017
    Amazing Thanks
     
  6. Amit_B

    Amit_B Member Language Board Moderator

    Messages:
    40
    Likes Received:
    21
    Joined:
    Oct 27, 2016
    Great tutorial and library :=)
     
  7. Gonzov

    Gonzov New Member

    Messages:
    1
    Likes Received:
    1
    Joined:
    Feb 23, 2017
    Nice job! Thank you!

    P.S. It would be great if you could provide the source code for the project. :=)
     
    HidroDF likes this.
  8. HidroDF

    HidroDF Member

    Messages:
    19
    Likes Received:
    2
    Joined:
    Jan 13, 2017
    Tryi to follow but I have these problem:

    [​IMG]
     
    Gonzov likes this.
  9. AgresivD

    AgresivD Member

    Messages:
    8
    Likes Received:
    14
    Joined:
    Jan 12, 2017
    try
    PHP:
    public static agrSQL sqlLink = new agrSQL();
     
    Gonzov likes this.
  10. HidroDF

    HidroDF Member

    Messages:
    19
    Likes Received:
    2
    Joined:
    Jan 13, 2017
    same... do you have the entire solution to use as 'base' script?
     
    Gonzov likes this.
  11. 0x5DC

    0x5DC New Member

    Messages:
    2
    Likes Received:
    0
    Joined:
    Apr 14, 2017
    Storing each players data in memory is bad design. Sure, use a collection to store connected players data, but doing this in bulk at startup for all registered users is silly. This is the whole purpose of having a SQL database.
     

Share This Page