Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - umar4911

#1
Command Manager


I had this command manager scripted long ago which I used in my old squirrel-based projects. Complete credits go to SLC as this command manager is a replica of the SqMod command manager and has a function of getting argument type made by him.




Installation

function onScriptLoad()
{
    CPlayer.rawnewmember("Authority", 1);
    dofile("CMD_Manager.nut", true);
}


function onPlayerCommand(player, cmd, arguments)
{
    local str = cmd + (arguments == null ? "" : " " + arguments);
    if(cmd != "") CMD_Manager.Run(player, player.Authority, str);
}



The code for CMD_Manager.nut can be found on the Github Repository.




Usage


Creating command

The syntax to create a command is:
CMD_Manager.Create(command, args_type, args_array, min_args, max_args, auth, protected, assoc)
Understanding the parameters

First argument is the command name.

Second are the command masks for each argument. At the moment it supports the following specifiers:

i The argument accepts integer.
f The argument accepts floating point number.
b The argument accepts boolean.
s The argument accepts string.
g This argument is a greedy argument. Anything after this argument is captured as a string and no further parsing is done.

And you can combine them if one argument accepts multiple types of values.

Let's say that your command expects integer or float for the first argument, boolean for the second, uppercase string for the third and integer, float or boolean for the fourth. Then your mask should be like:

"if|b|u|ifb"
That way the command system knows how to parse the parameters and what values to expect.

Third argument is an array of argument names.  For example, let's say I'm creating a register command with 3 arguments. I'll probably specify ["name", "password", "email"].

The fourth and fifth argument is the minimum and maximum arguments that the command needs. When calling the command you only need the minimum and the rest is optional. You can have up to 16 arguments. I believe that's a fair number.

The sixth argument defines the authority/level of the command. It is validated with the newly added player.Authority. So yea, you got yourself an easy admin system in it, just change the player's authority.
player.Authority = 5If the player's authority is equal to more than the command authority, then it is triggered.

The seventh argument defines whether you want to protect the command or validate it to the player's authority. When set to true, it checks whether the player's authority is equal to or more than the command's authority. When set to false, it skips this validation step.

The last argument is Assosicate. It defines whether to get command's  'args' in form of table or array. When set to true, values are received in table form or else in array form.


Once done, you need to bind an environment and a function with 2 parameters (player and arguments) to the command by for example,
CMD_Manager.Create().BindExec(this, function (player, args) {

});



Lets create a command sethealth
CMD_Manager.Create("sethealth", "s|i", ["Target", "HP"], 0, 2, 1, true, false).BindExec(this, function(player, args) {
    if(args.len() >= 2)
    {
        local plr = FindPlayer(args[2]);
        if(plr)
        {
            if(args[1] <= 255 && args[1] >= 0)
            {
                Message(format("%s changed the health of %s to %d", player.Name, plr.Name, args[1]));
                plr.Health = args[1];
            }
            else MessagePlayer("Health must be between 0 to 255.", player);
        }
        else MessagePlayer("Unknown player", player);
    }
    else MessagePlayer("Wrong syntax, use /sethealth <player> <hp>", player)
})
This command is set to work if the arguments passed by the player are in between 0 to 2, having authority 1. Since the Associate is defined as zero, the arguments are in form of an array. Now the same command but which Associate set to true:
CMD_Manager.Create("sethealth", "s|i", ["Target", "HP"], 0, 2, 1, true, true).BindExec(this, function(player, args) {
    if(args.rawin("Target") && args.rawin("HP"))
    {
        local plr = FindPlayer(args.Target);
        if(plr)
        {
            if(args[1] <= 255 && args[1] >= 0)
            {
                Message(format("%s changed the health of %s to %d", player.Name, plr.Name, args.HP));
                plr.Health = args.HP;
            }
            else MessagePlayer("Health must be between 0 to 255.", player);
        }
        else MessagePlayer("Unknown player", player);
    }
    else MessagePlayer("Wrong syntax, use /sethealth <player> <hp>", player)
})
The arguments are now in table form.



Error Handling:

In order to trigger errors for the commands, you need to define a BindFail function.

There are total 5 types of Errors defined in an Enum:
enum CMDErrorTypes {
    UnknownCommand,
    InsufficientAuth,
    UnsupportedArg,
    IncompleteArgs,
    SyntaxError
}

An example of BindFail function:
CMD_Manager.BindFail(this, function (type, player, cmd, msg) {

switch(type)
{
case CMDErrorTypes.UnknownCommand:
MessagePlayer("[#ffffff]Error - Command doesn't exist.", player);
break;
case CMDErrorTypes.InsufficientAuth:
MessagePlayer("[#FF3300]Error - Unauthorized Access.", player);
break;
case CMDErrorTypes.UnsupportedArg:
MessagePlayer(format("[#DDFF33]Error - Wrong type of parameter passed to command %s.", cmd), player);
break;
case CMDErrorTypes.IncompleteArgs:
MessagePlayer(format("[#FFDD33]Error - Incomplete arguments for command %s.", cmd), player);
break;
case CMDErrorTypes.SyntaxError:
MessagePlayer(format("[#ff0000]Error - [#ffffff]Command %s throwed an error: %s", cmd, msg), player);
break;
default:
print("Bind Fail called");
break;
}
})





All credits go to SLC for this post too as I stole some content of his :P





Some cool things that you can do for example:
[spoiler]
CMD_Manager.Create("cmds", "", [""], 0, 0, 1, true, true).BindExec(this, function (player, args) {
    local msg = "";
    foreach(listener in CMD_Manager.GetArray())
    {
        {
            if(msg != "") msg += ", ";
            msg += listener.Name;
        }
    }
    MessagePlayer(format("Available commands: %s", msg), player);
});

An example of having commands with the same function but different name (like wep, we)


{
    local exec = function (player, args) {
       if(args.rawin("code"))
    {
        try
        {
            local cscr = compilestring(args.code);
            cscr();
        }
        catch (e) MessagePlayer(format("Exection Error %s", e), player);
    }
    else MessagePlayer("/e ( Code )", player);
    }
    CMD_Manager.Create("e", "g", ["code"], 0, 1, 1, true, true).BindExec(this, exec);
    CMD_Manager.Create("exec", "g", ["code"], 0, 1, 1, true, true).BindExec(this, exec);
}
[/spoiler]
#2
VKs Winter Wars is originally the VKs Christmas Jolly Event but this time, the event has been shifted to another server.

New features:
- Event server is scripted in SqMod so you can get a smoother version of the event
- Reduced custom content thus less lag
- Better GUI for the event
- No 50-cap limit

For more info, refer to the forum thread or join our Discord server!


Trailer:

https://www.youtube.com/watch?v=mwR8Mjz2JCc
#3


EAD staff are back again presenting to you Season Three of EAD League 2021!
The event that everyone was waiting for to go out there and rock the battlefields with their clan mates!


If you haven't heard about it before, Let's see how it works:
  • Gather your squad and make a team application here.
  • There's a certain amount of rounds to be decided as soon as the teams are decided, in which each team plays one match/round and they don't have to play their matches in order.
  • Each team picks 2 bases from the base list. These bases will stay with them till the league ends.
  • No teams can pick similar bases.
  • The matches are usually 5 v 5, except if both teams agree to play with less than 5, that's okay too.
  • Four bases for each match, with a total of 8 rounds.
  • Team applications has specific requirements this year, Please check it out here before applying.
  • We're very strict about rules, so make sure you check them in the Rules & Regulations.

If you'd like to be part of the staff, Apply as a referee here.!
It's as simple as that. Further information can be found here.
Click here to join EAD League discord
If you have any questions, feel free to ask here and the staff will answer you shortly.

Have a nice one folks, We will be waiting for you.
#4
if you change your skin using player.Skin = skin; your weapon resets. In order to avoid that, add this in your script:

function CPlayer::SetSkin(skin) {
    local slot = this.Slot;
    this.Skin = skin;
    this.Slot = slot;
}

Now use:
player.SetSkin(skinid)


onPlayerSkinChange
If you want this event, use:

function CPlayer::SetSkin(skin) {
    local slot = this.Slot, oldskin = this.Skin;
    this.Skin = skin;
    this.Slot = slot;
  onPlayerSkinChange(this, oldskin, skin)
}

Event:
function onPlayerSkinChange(player, OldSkin, NewSkin) {
}
#6
VCMP Server Monitor

Even though it is easy to write the packets but I found this very cool npm library which shortens your work. It returns the all the server information so complete credits to the contributors of the library.


GameDig - Game Server Query Library

All the information about this library is present in it's GitHub Repository.

Link: https://github.com/gamedig/node-gamedig

Note: This library is not specifically for vcmp.


Example

I created a sample script using which you can get the information of a server in JSON. I deployed it on Heroku.

Replace ip and port with the server's Ip and port
https://vcmp-info.herokuapp.com/ip/port


Click here to get server information of LW


Click here to get server information of VKs


The source code is present in my Github Repository.

Example of the JSON code:
{
  "msg": "success",
  "state": {
    "name": "VKs official server [VRocker hosting]",
    "map": "",
    "password": false,
    "raw": {
      "version": "04rel006",
      "numplayers": 12,
      "gamemode": "United CA Mode v5.4.1",
      "map": "Vice City"
    },
    "maxplayers": 50,
    "players": [
      {
        "name": "=KF=SHy^LT"
      },
      {
        "name": "[RT]Martyrdom"
      },
      {
        "name": "[RT]ShadowJacK."
      },
      {
        "name": "[F2]MK14"
      },
      {
        "name": "=SdS=SupeR^DaviD*"
      },
      {
        "name": "[WSt]Jhanders"
      },
      {
        "name": "KeNgAhMeD2008"
      },
      {
        "name": "[KFt]Sos^"
      },
      {
        "name": "Jocoka"
      },
      {
        "name": "HUSSIENPRO"
      },
      {
        "name": "Jezza^++"
      },
      {
        "name": "Todor03"
      }
    ],
    "bots": [],
    "connect": "51.38.93.130:8194",
    "ping": 12
  }
}


#7
X3DEditor

I've seen VCMP scripters who are working with the GUI are not so familiar with the 3D elements. Since it is a part of my upcoming release, I thought to share it. This script is originally made for scripters who creates GUI in buildmode. Using this snippet, you can easily find the position, rotation and size of a 3D Element.

Note: This only supports DecUI

Understanding controls

It has total 3 types;
  • Position
  • Rotation
  • Size

Position
In order to enter the position changing mode, press 1 from keyboard.

Arrow up - Moves the element forward
Arrow down - Moves the element backward
Arrow left - Moves the element left
Arrow right - Moves the element right
Page up - Moves the element vertically upwards
Page down - Moves the element vertically downwards


Rotation
In order to enter the rotation changing mode, press 2 from keyboard.

Arrow Keys - Change the rotation respectively
Delete - Horizontally rotates to the left (backward)
Page down - Horizontally rotates to the right (forward)



Size
In order to enter the Size changing mode, press 3 from keyboard.

Arrow up - Decreases the size vertically
Arrow down - Increases the size vertically
Arrow left - Decreases the size horizontally
Arrow right - Increases the size horizontally


Saving & Exporting
In order to stop editing the element and export the data, press Backspace key.
This will return print the values and also copy them to the clipboard

Youtube Video

https://www.youtube.com/watch?v=e5k-ZElC55U


Code and example



The code and example is present on the Github Repository.



#8
Credits:

VC:MP Icons Font
This font allows to use icons in your GUI Labels. Here is the chart:



Originally it has more than 90 glyphs, try going through character map to view them all (some of them might be repeating).

It has all properties of a normal GUILabel. You can use TextColour, align, padding, flags, or whatever you want.

Download:
https://www.mediafire.com/file/x6068hfb5l7bhs4/FAEditUmar_unp.7z/file

Installation:
Paste the 7z file in store/fonts


Usage:
- Use FontName of a Label as "FAEditUmar"

Note: The size of some of the icons might be varying.
#9
I wrote this guide for a friend who wanted to know how to send data from server to client and how to use DecUI. I thought why not post here too.

The function is taken from here https://forum.vc-mp.org/?topic=4484 Credits: Seby
DecUI is taken from here https://forum.vc-mp.org/?topic=6775 Credits: NewK


P.S: Sorry in advance if it's a little messed up.

Comments are added in each code for more explanation.





okay first example. We are sending kills from the server which should show to the player using a label


In order to record the identifier bytes, we can use enumerations (enum as short) like

[noae][noae][noae][noae]enum ByteInfo {
Kills = 0x02
}
[/noae][/noae][/noae][/noae]

Let's set that as soon as player spawns, it is shown.

[noae][noae][noae][noae][noae]

enum ByteInfo {
Kills = 0x02
};


function onPlayerSpawn(player)
{
// The ByteInfo.Kills will record it's identifier
SendDataToClient(player, ByteInfo.Kills, status[player.ID].kills, status[player.ID].Deaths)

// We send 3 values to the client, in the order, byte, int, int
}

// here is the special func
function SendDataToClient( player, ... )
{
if( vargv[0] )
{
local   byte = vargv[0], len = vargv.len();
Stream.StartWrite();
Stream.WriteByte( byte );
if( 1 < len )
{
for( local i = 1; i < len; i++ )
{
switch( typeof( vargv[i] ) )
{
case "integer": Stream.WriteInt( vargv[i] ); break;
case "string": Stream.WriteString( vargv[i] ); break;
case "float": Stream.WriteFloat( vargv[i] ); break;
}
}
}
if( player == null ) Stream.SendStream( null );
else if( typeof( player ) == "instance" ) Stream.SendStream( player );
else return;
}
}
[/noae][/noae][/noae][/noae][/noae]



Now we have sent data from the server. Lets get those values in client side
[noae][noae][noae][noae][noae]
enum ByteInfo {
Kills = 0x02
};


function Server::ServerData(Data)
{
// the first parameter we sent for all the data packets will be a byte so lets get it
local byte = Data.ReadByte();
// the local will store it's value

//since we used ByteInfo.Kills for the kills label
switch (byte)
{
case ByteInfo.Kills:
// the next values we sent where kills and deaths in the order and both were int vals
local kills = Data.ReadInt(),
deaths = Data.ReadInt();
// values stored

// I'll use a func to make the labels
CreateKillsGUI(kills, deaths);
break;
default: break;
}
}

function CreateKillsGUI(kills, deaths) {
// you know the drill how to create GUILabels

// In order to help you, I'll use DecUI to Create a Label
local LabelKills = UI.Label({
    id = "KillsLabel" 
    Text = "Kills: " + kills
FontSize = 16
TextColour = Colour(255, 255, 255)
// It helps you do some cool alignments
align = "hud_bottom"
FontFlags = (GUI_FFLAG_BOLD)

// I want the label to move a little more down
move = {down = "10%"}
});


local LabelDeaths = UI.Label({
    id = "LabelDeaths" 
    Text = "Deaths: " + deaths
FontSize = 16
TextColour = Colour(255, 255, 255)
align = "hud_bottom"
FontFlags = (GUI_FFLAG_BOLD)

// deaths should be a bit more down
move = {down = "13%"}
});
}
[/noae][/noae][/noae][/noae][/noae]

Since we created the labels in DecUI, we will be needing the update the labels too.

Let's make like, the player uses the same byte to send the data and the same function to update the labels. We will edit our function

[noae][noae][noae][noae][noae]function CreateKillsGUI(kills, deaths) {
    // We used ID `KillsLabel` to create Label for kills

    if(UI.Label("KillsLabel") != null)
    {
        // if the value is not null, means a label with that ID exists
        UI.Label("KillsLabel").Text = "Kills: " + kills
    }
    else
    {
        // if the condition is null, means the label doesn't exist. Lets create it
        local LabelKills = UI.Label({
            id = "KillsLabel" 
            Text = "Kills: " + kills
            FontSize = 16
            TextColour = Colour(255, 255, 255)
            // It helps you do some cool alignments
            align = "hud_bottom"
            FontFlags = (GUI_FFLAG_BOLD)

            // I want the label to move a little more down
            move = {down = "10%"}
        });
    }
    // similar for the deaths

    if(UI.Label("LabelDeaths") != null)
    {
        UI.Label("LabelDeaths").Text = "Deaths: " + deaths
    }
    else
    {
        local LabelDeaths = UI.Label({
            id = "LabelDeaths" 
            Text = "Deaths: " + deaths
            FontSize = 16
            TextColour = Colour(255, 255, 255)
            align = "hud_bottom"
            FontFlags = (GUI_FFLAG_BOLD)

            // deaths should be a bit more down
            move = {down = "13%"}
        });
    }
}
[/noae][/noae][/noae][/noae][/noae]
Okay let's do some more cool things with DecUI. Let's create a progress bar for health instead of the text


We will be using event onPlayerHeathChange. Also we need to add another identifier in the enum.
Server Side
[noae][noae][noae][noae][noae]enum ByteInfo {
Kills = 0x02
HpBar = 0x03
};

function onPlayerHeathChange(player, oldHp, newHp)
{
//since we need to send the new health only and Health is a float value, we'll convert to integer
SendDataToClient(player, ByteInfo.HpBar, newHp);
}
[/noae][/noae][/noae][/noae][/noae]


Client-Side has a function `Script::ScriptLoad()` which runs when all files are downloaded and loaded in the server. Acts like onPlayerJoin

Client Side
[noae][noae][noae][noae][noae]// lets get the func scriptload
enum ByteInfo {
Kills = 0x02
HpBar = 0x03
};

function Script::ScriptLoad() {

    // first of all, we need to remove the player's health from hud
    Hud.RemoveFlags( HUD_FLAG_HEALTH );

    SetHealthBar(); // the function used to create the health bar
}

// to change the values of the progressbar when player's health change
function Server::ServerData(Data)
{
// the first parameter we sent for all the data packets will be a byte so lets get it
local byte = Data.ReadByte();
// the local will store it's value

switch (byte)
{
case ByteInfo.Kills: // kills label
// the next values we sent where kills and deaths in the order and both were int vals
local kills = Data.ReadInt(),
deaths = Data.ReadInt();
// values stored

// I'll use a func to make the labels
CreateKillsGUI(kills, deaths);
break;

        case ByteInfo.HpBar: //GUI Health bar
            // we sent player's health which is in an int value. Lets store that in a variable
            local health = Data.ReadInt();

            // lets create using a func again
            SetHealthBar(health);
        break;
default: break;
}
}

//now the function itself
function SetHealthBar(health = 100) {

    // we will use canvas and add progress bar as its child so we can easily position the label

    // condition to check if the health was already present
    if(UI.Canvas("HealthCanvas") == null)
    {
        local hpcan = UI.Canvas({
            id = "HealthCanvas" 
            // another cool func in DecUI
            RelativeSize = ["7%", "3.5%"] // parameters are width and height, using percent means the part of the screen size of the player
           
            // we want it at the position of old health bar and hud_left doesn't exist :c
            align = "hud_right"
            move = {left = "19.5%", down = "8.5%"}               
           
            // lets add a progressbar but as a child of the canvas
            children = [
                // progressbar
                UI.ProgressBar({
                    id = "HealthBar"
                    RelativeSize = ["100%", "100%"] // it will inherit the size of the canvas since canvas is it's parent


                    // some basic things
                    MaxValue = 100
                    Thickness = 2
                    StartColour = Colour(255, 77, 77)
                    EndColour = Colour(150, 40, 40)
                    selectedColour = Colour(255, 100, 100)
                    Value = health
                })
                // now lets add a label
                UI.Label({
                    id = "HealthLabel" 
                    Text = health + "%"
                    FontSize = 12
                    TextColour = Colour(255, 255, 255)
                    align = "center" // it will align itself according to the canvas since canvas is the parent. center means to the center of the canvas
                })
            ]
        });
    }
    else
    {
        // when we receive the data from the server when player health is changed


        //if the canvas is already present, then obv children will also be. lets change their values
        UI.ProgressBar("HealthBar").Value = health;
        UI.Label("HealthLabel").Text = health + "%";   
    }
}
[/noae][/noae][/noae][/noae][/noae]
#10
Bugs and Crashes / [BUG] GUILabel.Size
Apr 06, 2020, 06:44 PM
Description
GUILabel.Size doesn't change when GUILabel.FontSize is changed

Reproducible
Always

What you were doing when the bug happened
I changed FontSize and printed the values

What you think caused the bug
The Developers
#11
<?xml version="1.0" encoding="ASCII" ?>
<itemlist>
 <item model="1083" name="Home">
  <position x="-34.6886" y="1763.63" z="32.1387" />
  <rotation format="axisangle" x="0" y="0" z="-0.703279" angle="-0.710914" />
 </item>
</itemlist>

What can be other formats for rotation except axisangle? Is there any for Euler?
#12
Support / Ping starting spiking
Jun 30, 2019, 05:01 AM
I have transworld internet, 20mbps package. Using speedtest.net, I get around 16 Mbps downloading and 18 Mbps uploading. Like a month before, I had 150 pings in almost all servers including vks, lw, ec, ptp, etc. Now I have the same internet, same speed but my ping now spikes a lot. It reaches to 1K or even 2K. Average ping is like 300 now. I need help here. I get kicked a lot too. Note: I got no new apps in my PC and I also tried by closing all the applications in the background using the internet including discord.  I can't figure the issue out. Any help will be appreciated.
#13
I got a map which is loaded perfectly and now I want to load its custom radar. What are sections and regions of map? How can I trace the section and region of a location?
#14
Bugs and Crashes / [Bug] FPS Limit Uncapped
Apr 12, 2019, 05:33 AM
Description
If you press escape, the limit of 60 fps is uncapped. I get about 450-750 fps

Reproducible
Always

What you were doing when the bug happened
When I go in the menu (press escape) then I change mouse sensitivity.

What you think caused the bug
The new update

@Stormeus
#15
Bugs and Crashes / [Bug] Chat Desync
Apr 09, 2019, 04:06 PM
Description
When playing, after about 15-45 mins, the chat desync and it loads the chat from chat like  "=EK=UmaR^ joined the server"
Note: I didn't modify screen size and it happened after the new update

Reproducible
Always

What you were doing when the bug happened
Usually Dming


What you think caused the bug
Rel006 update

@Stormeus
#16
the livemap plugin, its syntax, how to integrate with a website and how to make it work?
#17
in debug, when trying to play radio, it gives error code 20. What does that mean??
#18
Support / Banned from vc-mp forum
Mar 21, 2019, 06:27 AM
Well, It shows on my mobile that I am banned from vcmp forum, reason using hacks which I never did and on PC, its working perfectly
#19
Vps = CentoLinux version 7

when loading Hashing plugin, it says:

Plugin error >> dlopen() 'plugins/hashing04rel64.so' failed: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by plugins/hashing04rel64.so)
Failed to load plugin: hashing04rel64

what's the fix
#20
General Discussion / the server domain
Mar 05, 2019, 01:43 PM
v04.vc-mp.org is not working thus, no files are being downloaded uploaded to the host. It includes the files uploaded by stormeus