Author Topic: Bitwise Operations  (Read 3188 times)

Vortrex

  • Full Member
  • ***
  • Posts: 267
  • Karma: +54/-73
    • View Profile
Bitwise Operations
« on: May 22, 2014, 01:51:59 am »
I am writing this tutorial today to assist scripters with learning how to use bitwise operators.

If you don't know what a bitwise operator is, or how to use them, view the wikipedia article at:
http://en.wikipedia.org/wiki/Bitwise_operation
It should help explain the use of these operations.

You might have used a bitwise operator before, as the client-side key state change function in LU uses them. For this tutorial, I will be using the example of an admin permissions system.

Lets say we have a few things that admins on your server can do:
- Kick
- Ban
- Freeze
- Mute
- Teleport

We can define these things inside an enum, and give each one a name:
Code: [Select]
enum AdminFlagTypes
{
Kick = 1,
Ban = 2,
Freeze = 4,
Mute = 8,
Teleport = 16
}

You might have noticed that I increased the number by doubling it from the last one. This is required for the bitwise operations to be used. Start with 1, and work your way up. Remember, there is a limit, as the LU server is 32 bit only and therefore can only use a number that is less than 32 digits long.

Now, onto the actual operations ...
There are four main types of operators:
"AND"
"OR"
"XOR"
"NOT"

The "AND" operator is used via an ampersand (&).
The "OR" operator is used via a pipe (|)
The "XOR" is used via the caret (^)
The "NOT" operator is used via a tilde (~)

Lets create an array that holds admin permissions for players:
Code: [Select]
AdminFlags <- array( 128 , 0 );
Okay, so we have our flag types enum and admin flags for each player created. When a player connects, you can load their permissions straight into their slot in the array. It will be in the form of an integer that ranges from 1 to 32 digits in length.

For now, we are going to assume that no player has any permissions set. We can add some by using the "OR" operator. You can make a command that allows you to kick other players:
Code: [Select]
function onPlayerCommand( player , command , params )
{
switch( command.tolower( ) )
{
case "allowkick":
AdminFlags[ player.ID ] <- AdminFlags[ player.ID ] | AdminFlagTypes.Kick;
break;
}
}
Note that only one pipe is used here. This is appending the Kick flag onto your flags.

To remove a flag, you have to use the AND, and NOT operator. If you don't have the flag set, then this will have no effect.
Code: [Select]
function onPlayerCommand( player , command , params )
{
switch( command.tolower( ) )
{
case "denykick":
AdminFlags[ player.ID ] <- AdminFlags[ player.ID ] & ~AdminFlagTypes.Kick;
break;
}
}
This is pretty much saying "AdminFlags should equal the current AdminFlags and NOT the Kick flag"

Now, what happens when we want to see if you have the kick flag?
Code: [Select]
function onPlayerCommand( player , command , params )
{
switch( command.tolower( ) )
{
case "cankick":
if( AdminFlags[ player.ID ] & AdminFlagTypes.Kick )
{
// You have the kick flag
}
else
{
// You do NOT have the kick flag
}
break;
}
}
In a more english set of terms, this is saying "If the AdminFlags are set AND have a Kick flag present, then they can kick, otherwise (else) they cannot kick"

This may seem pretty complicated to most, but using it for a while will be a bit wise (pun intended). To store permissions, all you need to do is save the number that AdminFlags[ player.ID ] has.

Thanks for reading!

 

© Liberty Unleashed Team.