Re: To optimize our GM and our Server improves. -
xVIP3Rx - 23.12.2013
Quote:
Originally Posted by pds2k12
newbienoob - There's a method that is much better than that  , I will share it to you, you could use the function gettime, to create a timer for a command, I used to use the first method, creating a second timer and loop it, but when the callback gets larger, You will experience lag, but the code below is just amazing
pawn Code:
CMD:healme(playerid, params[]) { static HealTimer[ MAX_PLAYERS ] = { 0, ... } ;
if( (gettime( ) - HealTimer[playerid] ) < 60) return SendClientMessage(playerid, -1, "Please wait 1 minute before using this command again!");
HealTimer[playerid] = gettime();
SetPlayerHealth(playerid, 100); IsHealed[playerid] = 1; return 1; }
|
That's better..
But let's say I want to send a message when I'm able to heal again... I'll be forced to use a timer.. And newbienoobs' code (I think) will be better then using a timer...
Re: To optimize our GM and our Server improves. - Patrick - 23.12.2013
Quote:
Originally Posted by newbienoob
The code I posted was just an example. I could use random messages, unmuting/unjailing, updating hour's playing... etc. Something like this
Is it a good way?
|
Yes, I'd say it's a good way, doing that. instead of using
ALOT of timer.
Re: To optimize our GM and our Server improves. -
SuperViper - 23.12.2013
Quote:
Originally Posted by Konstantinos
No need to use strmid or any temporary string to store the name. Just:
pawn Code:
GetPlayerName(playerid, PlayerName[playerid], MAX_PLAYER_NAME);
|
If you want to keep using the custom function to gather names, you could use:
pawn Code:
new playersName[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerDisconnect(playerid)
{
playersName[playerid][0] = '\0';
return 1;
}
GetPlayersName(playerid)
{
if(isnull(playersName))
{
GetPlayerName(playerid, playersName, MAX_PLAYER_NAME);
}
return playersName;
}
This would be a better alternative for users who have a big script using this function already.
Re: To optimize our GM and our Server improves. -
xVIP3Rx - 23.12.2013
Quote:
Originally Posted by SuperViper
If you want to keep using the custom function to gather names, you could use:
pawn Code:
new playersName[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerConnect(playerid) { playersName[playerid][0] = '\0'; return 1; }
GetPlayersName(playerid) { if(isnull(playersName)) { GetPlayerName(playerid, playersName, MAX_PLAYER_NAME); }
return playersName; }
This would be a better alternative for users who have a big script using this function already.
|
What about
pawn Code:
new playersName[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerDisconnect(playerid)
{
GetPlayerName(playerid, playersName[playerid], MAX_PLAYER_NAME);
return 1;
}
GetPlayersName(playerid)
{
return playersName[playerid];
}
?
I already tried that.. But It gave me a mistag warning and still working on it..so maybe thats why ?
Re: To optimize our GM and our Server improves. -
Konstantinos - 23.12.2013
Quote:
Originally Posted by SuperViper
If you want to keep using the custom function to gather names, you could use:
pawn Code:
new playersName[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerDisconnect(playerid) { playersName[playerid][0] = '\0'; return 1; }
GetPlayersName(playerid) { if(isnull(playersName)) { GetPlayerName(playerid, playersName, MAX_PLAYER_NAME); }
return playersName; }
This would be a better alternative for users who have a big script using this function already.
|
Defining it would make it easier I believe.
pawn Code:
#define GetName(%0) Player_Name[%0]
static
Player_Name[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerConnect(playerid)
{
GetPlayerName(playerid, Player_Name[playerid], MAX_PLAYER_NAME);
return 1;
}
Re: To optimize our GM and our Server improves. - Patrick - 23.12.2013
Quote:
Originally Posted by Konstantinos
Defining it would make it easier I believe.
pawn Code:
#define GetName(%0) Player_Name[%0]
static Player_Name[MAX_PLAYERS][MAX_PLAYER_NAME];
public OnPlayerConnect(playerid) { GetPlayerName(playerid, Player_Name[playerid], MAX_PLAYER_NAME); return 1; }
|
I never thought of that, that is pretty
smart
Re: To optimize our GM and our Server improves. -
PowerPC603 - 23.12.2013
I've also found out to optimize command a bit.
This my old /fuel command:
Code:
// Refuel the player's vehicle
COMMAND:fuel(playerid, params[])
{
// Setup local variables
new vID;
// Send the command to all admins so they can see it
SendAdminText(playerid, "/fuel", params);
// Check if the player has logged in
if (APlayerData[playerid][LoggedIn] == true)
{
// Check if the player's admin-level is at least 1
if (APlayerData[playerid][PlayerLevel] >= 1)
{
// Check if the player is inside a vehicle
if (IsPlayerInAnyVehicle(playerid))
{
// Get the vehicleid
vID = GetPlayerVehicleID(playerid);
// Refuel the vehicle
AVehicleData[vID][Fuel] = MaxFuel;
// Let the player know about it
SendClientMessage(playerid, 0x00FF00FF, "Your vehicle is refuelled");
}
else
SendClientMessage(playerid, 0x00FF00FF, "You're not driving a vehicle");
}
else
return 0;
}
else
return 0;
// Let the server know that this was a valid command
return 1;
}
You can see that this code can go pretty far to the right if even more if-statements are under it.
And it's sometimes hard to see where a code-block ends if there are many instructions in a block.
I've optimized it to this:
Code:
// This command allows you to refuel your vehicle for free (admins only)
COMMAND:fuel(playerid, params[])
{
// If a player hasn't logged in properly, he cannot use this command
if (APlayerData[playerid][LoggedIn] == false) return 0;
// If the player has an insufficient admin-level (he needs level 1), exit the command
if (APlayerData[playerid][AdminLevel] < 1) return SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}Only admins level 1 can use this command");
// If the player is on the class-selection menu, block the command
if ((GetPlayerState(playerid) == PLAYER_STATE_WASTED) || (GetPlayerState(playerid) == PLAYER_STATE_NONE)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You cannot use this command while using class-selection");
// Exit the command if the player is not the driver of a vehicle
if (GetPlayerVehicleSeat(playerid) != 0) return SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You're not driving a vehicle");
// Setup local variables
new vid, engine, lights, alarm, doors, bonnet, boot, objective;
// Get the vehicleid
vid = GetPlayerVehicleID(playerid);
// Refuel the vehicle
AVehicleData[vid][Fuel] = MaxFuel;
// Also (re-)start the engine and turn on the lights in case the vehicle was completely out of fuel
GetVehicleParamsEx(vid, engine, lights, alarm, doors, bonnet, boot, objective);
SetVehicleParamsEx(vid, 1, 1, alarm, doors, bonnet, boot, objective);
// Let the player know about it
SendClientMessage(playerid, 0xFFFFFFFF, "{00FF00}Your vehicle is refuelled");
// Let the server know that this was a valid command
return 1;
}
Here you can see that any condition that would fail the command is on top of the command.
And the rest of the code doesn't need to be nested in alot of underlaying if-statements.
Also the new command has more functionality in it but has become shorter as well by this new approach.
Re: To optimize our GM and our Server improves. -
Bakr - 23.12.2013
Quote:
Originally Posted by xVIP3Rx
So you say that the end user is able to get the global "New"s in samp ?
Or you mean for other programs ?
|
Lets say you create a library that runs on a specified timer. In the include you retrieve this timer and store it in a variable so you can delete it at server close - this variable is g_Timer. In your script that you include that library, they can access and modify the g_Timer variable, which in return can completely screw up the library. This is just one example, there are multiple other cases.
Here is a quick example:
pawn Code:
// timer.inc
// the include that runs off the timer
// declare the variable to store the timer ID so we can kill it later on
new g_Timer;
// Initialize the timer when the mode starts by hooking OnGameModeInit
hook OnGameModeInit() { g_Timer = SetTimer(...); }
// Kill the timer when the mode ends by hooking OnGameModeExit()
hook OnGameModeExit() { KillTimer(g_Timer); }
Now, here is the script that includes that library
pawn Code:
// test.pwn
#include <timer>
stock RandomFunction()
{
// Here the "g_Timer" variable's value is altered meaning we no longer have the correct
// timer ID to kill via our library
g_Timer = SetTimer(...);
}
If you had declared the "g_Timer" variable as static, the test.pwn script wouldn't have been able to access the variable and screw things up. The static keyword is not only there to prevent things like this, but also hide implementation details from the end user. It's good programming practice. Like I've said, look up encapsulation.
Re: To optimize our GM and our Server improves. -
Djole1337 - 23.12.2013
pawn Code:
stock ProvedAtRandom()
{
new Random = random(3);
switch(Random)
{
case 0: SendRconCommand("gmx");
case 1: SendRconCommand("password Tutorial.");
case 2: SendRconCommand("reloadfs Tutorial");
}
return Random;
}
Can be shortened down to:
pawn Code:
stock ProvedAtRandom() {
new Random = random(3);
SendRconCommand((Random == 0) ? ("gmx") : ((Random == 1) ? ("password Tutorial") : ("reloadfs Tutorial")));
return Random;
}
Re: To optimize our GM and our Server improves. -
SuperViper - 23.12.2013
Quote:
Originally Posted by Djole1337
pawn Code:
stock ProvedAtRandom() { new Random = random(3); switch(Random) { case 0: SendRconCommand("gmx"); case 1: SendRconCommand("password Tutorial."); case 2: SendRconCommand("reloadfs Tutorial"); } return Random; }
Can be shortened down to:
pawn Code:
stock ProvedAtRandom() { new Random = random(3); SendRconCommand((Random == 0) ? ("gmx") : ((Random == 1) ? ("password Tutorial") : ("reloadfs Tutorial"))); return Random; }
|
Shortening code isn't always optimizing it.
Respuesta: To optimize our GM and our Server improves. -
Swedky - 24.12.2013
The reason for which I did this tutorial was to help which newly begin in this one language (PAWN, 'Pawno' is only an IDE used to programme with human reading, if I am not wrong) and they would like to learn.
Since they will see in my date of record, it was for 6 months I programme, and try to help in what could.
Regards and thanks to all for the constructive critiques and the support
.
Re: To optimize our GM and our Server improves. - Patrick - 24.12.2013
I am not sure if this
speedtest is
accurate but its still shows that
switch is faster than
ternary operator, using
Slice Pawn Playground switch prints
Null( 0 ), but I am not sure if my code is right, but
Ternary Operator prints around
70+
Switch speed test Code
pawn Code:
#include <a_samp>
main()
{
new
StartCount,
EndCount,
i
;
StartCount = GetTickCount();
while(++i < 1000)
{
switch(i)
{
case 1000: print(" ");
}
}
EndCount = GetTickCount();
printf("Switch Statement Speed to locate 1000 i's: %d", (EndCount - StartCount));
}
Result
Code:
Switch Statement Speed to locate 1000 i's: 0
Error: read EIO (EIO)
The server stopped.
Ternary Operator speed test code
pawn Code:
#include <a_samp>
main()
{
new
StartCount,
EndCount,
i
;
StartCount = GetTickCount();
while(++i < 1000)
{
print(( i == 1000 ) ? ( " " ) : ( " " ));
}
EndCount = GetTickCount();
printf("Ternary Operator Speed to locate 1000 i's: %d", (EndCount - StartCount));
}
Result
Code:
Ternary Operator Speed to locate 1000 i's: 72
Error: read EIO (EIO)
The server stopped.
Correct me if I did anything wrong on my code, and test it your self using this link:
http://slice-vps.nl:7070/
Respuesta: To optimize our GM and our Server improves. -
Swedky - 24.12.2013
A friend of mine did a speed test with static and new. (I translate it in order that they could understand it):
Quote:
Originally Posted by JustBored
Excuse the idea of re-living through the post, but eh condition doing a few tests of speed, and I realized that using global variables (static) then to be using it in the script, it is more rapid than them to be creating again and again.
For example, it is better to do this:
pawn Code:
static var1[400]; main() { format(var1, sizeof(var1), "ola=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1);
That this:
pawn Code:
new var1[400]; main() { format(var1, sizeof(var1), "ola=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1); format(var1, sizeof(var1), "123=%d", 1); printf(var1);
Note: I used 400 cells to make the speed tests more notable. Here my results:
Code:
[00:45:24] Static: 30 miliseconds
[00:45:24] New: 65 miliseconds
[00:45:24] New global: 34 miliseconds
And the code:
pawn Code:
#include <a_samp>
static var1[400]; new var3[400]; main() { new a = GetTickCount(); for(new i = 0; i < 300000; i++) { var1 = ""; var1 = "SHALALALOMSHALALALOMLILONLONLON='%d', OAODWIEQIOWUEOQWIE='%s', a='%i'Olakease"; } printf("Static: %d milisegundos", GetTickCount() - a);
a = GetTickCount(); for(new i = 0; i < 300000; i++) { new var2[400]; var2 = "SHALALALOMSHALALALOMLILONLONLON='%d', OAODWIEQIOWUEOQWIE='%s', a='%i'Olakease"; } printf("New: %d milisegundos", GetTickCount() - a);
a = GetTickCount(); for(new i = 0; i < 300000; i++) { var3=""; var3 = "SHALALALOMSHALALALOMLILONLONLON='%d', OAODWIEQIOWUEOQWIE='%s', a='%i'Olakease"; } printf("New global: %d milisegundos", GetTickCount() - a); }
I used long values to make notice more the topic. Any mistake warn me.
|
I add it for the one that should want to extract the doubts
.
Re: To optimize our GM and our Server improves. -
Mister0 - 15.08.2016
From where can I take the incldue
#include <a_timers> // Here the name of the include.?
I put this
Code:
stock Timer:operator = (t) return Timer:t;
stock StartTimer(&Timer:timer, const TimerTime)
{
timer = ((gettime())+(TimerTime));
return 1;
}
stock ObtainTimer(Timer:timer)
{
new CurrentTime = gettime();
return (_:timer-CurrentTime <= 0) ? (0) : (_:timer-CurrentTime);
}
stock bool:TimerHasHappened(Timer:timer)
{
return (ObtainTimer(_:timer) <= 0) ? (true) : (false);
}
And i have error tag mishmatch at this
StartTimer(reported[playerid], 60000);
Respuesta: Re: To optimize our GM and our Server improves. -
Swedky - 17.10.2016
Quote:
Originally Posted by Mister0
From where can I take the incldue
#include <a_timers> // Here the name of the include.?
I put this
Code:
stock Timer:operator = (t) return Timer:t;
stock StartTimer(&Timer:timer, const TimerTime)
{
timer = ((gettime())+(TimerTime));
return 1;
}
stock ObtainTimer(Timer:timer)
{
new CurrentTime = gettime();
return (_:timer-CurrentTime <= 0) ? (0) : (_:timer-CurrentTime);
}
stock bool:TimerHasHappened(Timer:timer)
{
return (ObtainTimer(_:timer) <= 0) ? (true) : (false);
}
And i have error tag mishmatch at this
StartTimer(reported[playerid], 60000);
|
Sorry for late reply.
You should write tag before your var name:
pawn Code:
new Timer:reported[MAX_PLAYERS];
Also, here is a best version:
pawn Code:
#define StartTimer(%1,%2) %1 = gettime() + %2
#define GetTimerLeft(%1) ((%1 - gettime() <= 0) ? (0) : (_:%1 - gettime()))
This version doesn't need tag:
pawn Code:
#include <a_samp>
#include <ZCMD>
static MoneyTimer[MAX_PLAYERS];
#define StartTimer(%1,%2) %1 = gettime() + %2
#define GetTimerRemaining(%1) ((%1 - gettime() <= 0) ? (0) : (%1 - gettime()))
CMD:money(playerid)
{
if(GetTimerRemaining(MoneyTimer[playerid]) != 0) return SendClientMessage(playerid, -1, "* You can't use this command now.");
GivePlayerMoney(playerid, 5000);
StartTimer(MoneyTimer[playerid], 5 * 60); // 5s * 60s = 5m
return 1;
}
This old thread make me cry