08.06.2015, 16:20
Released on: 8th of June 2015
Last updated: ?
__________________________________________________ _______________________________________________
Intro:
Firstly, I couldn't have thought of a better topic name, but meh...
So, apparently, I'm back to SA-MP (kinda). Long story short, I've rewritten/recompiled/refurbished few of my old includes and now releasing them all together in this pack. I tried to document well each and every include in this post. Currently, this 'pack release' contains 7 includes, while in very near future it will contain 3 more, meaning 10 total. I'll be using ZCMD for commands examples, as well as gaining help from the sscanf. Anyways, lets start.
__________________________________________________ _______________________________________________
Content:
- BanClient.inc - default "Ban" function extension
- KickClient.inc - default "Kick" function extension
- TimeBan.inc* - rewritten temporar ban system previously named "fban.inc"
- CustomMoney.inc* - rewritten old, crappy, Dini-file-system-using, custom money system
- OnPlayerChangeAngle.inc - once part of "opc.inc", now standalone include
- OnPlayerChangePosition.inc - once part of "opc.inc", now also standalone include
- Logger.inc - small logging include that let's you log certain functions
- ClanSystem.inc [WIP] [NYR] - rewritting popular clan system include
- SetPlayerView.inc [WIP] [NYR] - rewritting include that introduces 4 new camera views
- CreateModShop.inc [WIP] [NYR] - partially done, allows you to create Loco, TransFender or Arch mod shop practically anywhere, with even better mod selection menu and stuff
Includes with "*" means that they're using Blazing User Database include made by Slice.
Also, please add this at the end of your "#include"'s wherever you're going to use "TimeBan.inc" and "CustomMoney.inc":
pawn Код:
#if defined _TimeBan_included
#if defined _CustomMoney_included
#error "Can't have TimeBan.inc and CustomMoney.inc in same filterscript/gamemode."
#endif
#endif
__________________________________________________ _______________________________________________
BanClient.inc
There is only one function present in this include. There's a 100ms delay in player banning due to inability to properly call some action (e.g. SendClientMessage, ShowPlayerDialog, etc.) right before the actual banning / while using the "Ban" function. Once part of the newkb.inc.
PHP код:
native BanClient(...);
PHP код:
COMMAND:ban(playerid ,params[])
{
/*
First parameter defines ban type, and in this case there are 3:
BAN_TYPE_NORMAL -> 5, similiar to default "Ban" function
BAN_TYPE_IP -> 6, IP bans the client
BAN_TYPE_RANGE -> 7, range bans client's IP address.
Second parameter represents the ID of the player you want to ban.
If the given ID is equal to INVALID_PLAYER_ID a.k.a. -1, all
players in the server are getting banned. If you want
to ban specific player, provide an ID of that player.
Third parameter gives the Admin an opportunity to choose between
2 different notification types. One is NOTIFY_TYPE_MSG (0), which sends
the message either to all players, specific player or RCON. Other
one is NOTIFY_TYPE_DIALOG (1), which informs the banned player about
action taken against them and their account.
Fourth parameter is the reason from which Admin decided to ban the
player. The reason gets formatted in a message, which is then displayed
in the chosen way.
*/
if(IsPlayerAdmin(playerid))
{
new ban_type, notify_type, ban_id = INVALID_PLAYER_ID, reason[50];
if(!sscanf(params, "idis[50]", ban_type, ban_id, notify_type, reason))
{
switch(ban_type)
{
case BAN_TYPE_NORMAL:
{
if(ban_id == INVALID_PLAYER_ID) BanClient(BAN_TYPE_NORMAL);
else if(IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
switch(notify_type)
{
case NOTIFY_TYPE_MSG:
{
new message[256];
format(message, sizeof(message), "* Player %d has been banned! (Reason: %s)", ban_id, reason);
BanClient(BAN_TYPE_NORMAL, ban_id, NOTIFY_TYPE_MSG, NOTIFY_ALL, message, 0xFFFFFFF);
return 1;
}
case NOTIFY_TYPE_DIALOG:
{
new message[256];
format(message, sizeof(message), "You have been banned from this server!\n\nReason: %s", reason);
BanClient(BAN_TYPE_NORMAL, ban_id, NOTIFY_TYPE_DIALOG, NOTIFY_PLAYER, "BANNED!", message, "OK");
return 1;
}
}
}
else if(!IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
SendClientMessage(playerid,-1,"WARNING: Player is not connected!");
return 1;
}
return 1;
}
case BAN_TYPE_IP:
{
if(ban_id == INVALID_PLAYER_ID) BanClient(BAN_TYPE_IP);
else if(IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
switch(notify_type)
{
case NOTIFY_TYPE_MSG:
{
new message[256];
format(message, sizeof(message), "* Player %d has been IP banned! (Reason: %s)", ban_id, reason);
BanClient(BAN_TYPE_IP, ban_id, NOTIFY_TYPE_MSG, NOTIFY_ALL, message, 0xFFFFFFF);
return 1;
}
case NOTIFY_TYPE_DIALOG:
{
new message[256];
format(message, sizeof(message), "You have been IP banned from this server!\n\nReason: %s", reason);
BanClient(BAN_TYPE_IP, ban_id, NOTIFY_TYPE_DIALOG, NOTIFY_PLAYER, "IP BANNED!", message, "OK");
return 1;
}
}
}
else if(!IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
SendClientMessage(playerid,-1,"WARNING: Player is not connected!");
return 1;
}
return 1;
}
case BAN_TYPE_RANGE:
{
if(ban_id == INVALID_PLAYER_ID) BanClient(BAN_TYPE_RANGE);
else if(IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
switch(notify_type)
{
case NOTIFY_TYPE_MSG:
{
new message[256];
format(message, sizeof(message), "* Player %d has been range banned! (Reason: %s)", ban_id, reason);
BanClient(BAN_TYPE_RANGE, ban_id, NOTIFY_TYPE_MSG, NOTIFY_ALL, message, 0xFFFFFFF);
return 1;
}
case NOTIFY_TYPE_DIALOG:
{
new message[256];
format(message, sizeof(message), "You have been range banned from this server!\n\nReason: %s", reason);
BanClient(BAN_TYPE_RANGE, ban_id, NOTIFY_TYPE_DIALOG, NOTIFY_PLAYER, "RANGE BANNED!", message, "OK");
return 1;
}
}
}
else if(!IsPlayerConnected(ban_id) && ban_id != INVALID_PLAYER_ID)
{
SendClientMessage(playerid,-1,"WARNING: Player is not connected!");
return 1;
}
return 1;
}
}
return 1;
}
else SendClientMessage(playerid,-1,"USAGE: /ban <ban_type> <ban_id> <notify_type> <reason>");
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
This include also introduces 3 new disconnet reasons. Here's very bare example of usage.
PHP код:
public OnPlayerDisconnect(playerid, reason)
{
switch(reason)
{
case DC_REASON_BAN:
{
printf("[Disconnect] Player %d got banned!", playerid);
return 1;
}
case DC_REASON_BAN_IP:
{
printf("[Disconnect] Player %d got IP banned!", playerid);
return 1;
}
case DC_REASON_BAN_RANGE:
{
printf("[Disconnect] Player %d got range banned!", playerid);
return 1;
}
}
return 1;
}
KickClient.inc
There is also only one function present in this include. There's a 100ms delay in player kicking due to inability to properly call some action (e.g. SendClientMessage, ShowPlayerDialog, etc.) right before the actual banning / while using the "Kick" function. Yes, you can guess, it's the same deal as with the "BanClient" include, just this time it's regarding "Kick" function. Once part of the newkb.inc.
PHP код:
native KickClient(...);
PHP код:
COMMAND:kick(playerid ,params[])
{
/*
First parameter represents the ID of the player you want to kick.
If the given ID is equal to INVALID_PLAYER_ID a.k.a. -1, all
players in the server will be kicked. If you want
to kick specific player, provide an ID of that player.
Second parameter gives the Admin an opportunity to choose between
2 different notification types. One is NOTIFY_TYPE_MSG, which sends
the message either to all players, specific player or RCON. Other
one is NOTIFY_TYPE_DIALOG, which informs the banned player about
action taken against them and their account.
Third parameter is the reason from which Admin decided to kick the
player. The reason gets formatted in a message, which is then displayed
in the chosen way.
*/
if(IsPlayerAdmin(playerid))
{
new kick_id = INVALID_PLAYER_ID, notify_type, reason[50];
if(!sscanf(params, "dis[50]", kick_id, notify_type, reason))
{
if(kick_id == INVALID_PLAYER_ID) KickClient();
else if(IsPlayerConnected(kick_id) && kick_id != INVALID_PLAYER_ID)
{
switch(notify_type)
{
case NOTIFY_TYPE_MSG:
{
new message[256];
format(message, sizeof(message), "* Player %d has been kicked! (Reason: %s)", kick_id, reason);
KickClient(kick_id, NOTIFY_TYPE_MSG, NOTIFY_ALL, message, 0xFFFFFFF);
return 1;
}
case NOTIFY_TYPE_DIALOG:
{
new message[256];
format(message, sizeof(message), "You have been kicked from this server!\n\nReason: %s", reason);
KickClient(kick_id, NOTIFY_TYPE_DIALOG, NOTIFY_PLAYER, "KICKED!", message, "OK");
return 1;
}
}
}
else if(!IsPlayerConnected(kick_id) && kick_id != INVALID_PLAYER_ID)
{
SendClientMessage(playerid,-1,"WARNING: Player is not connected!");
return 1;
}
}
else SendClientMessage(playerid,-1,"USAGE: /kick <kick_id> <notify_type> <reason>");
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
And yet another bare usage of the new-old disconnect reason.
PHP код:
public OnPlayerDisconnect(playerid, reason)
{
switch(reason)
{
case DC_REASON_KICK:
{
printf("[Disconnect] Player %d got kicked!", playerid);
return 1;
}
}
return 1;
}
TimeBan.inc
Basically, a rewritted fban.inc. Here's the list of functions.
PHP код:
native TimeBan(name[], reason[], hours, minutes, seconds);
native IsPlayerTimeBanned(name[]);
native GetPlayerTimeBanInfo(name[], &year, &month, &day, &hour, &min, &sec);
native UnbanPlayer(name[]);
/*these two are made to ease up some stuff in the include, ignore them completely
or use in your further implementation*/
native GetPlayerId(name[]);
native GetName(playerid);
Lets try and use this stuff in an example.
PHP код:
COMMAND:timeban(playerid,params[])
{
/*
First parameter represents the ID of the player you want to temporarily ban.
Second parameter is the amount of hours player will be banned.
Third parameter is the amount of minutes that player will be banned, plus
the already given hours.
Fourth parameter is the amount of seconds that player will remain but, along
with the already given hours and minutes.
Fifth parameter is the reason from which Admin decided to kick the
player. The reason gets formatted in a message, which is then displayed
in the chosen way.
*/
if(IsPlayerAdmin(playerid))
{
new pid, h, m, s, reason[50];
if(!sscanf(params, "diiis[50]", pid, h, m, s, reason))
{
TimeBan(GetName(pid), reason, h, m, s);
return 1;
}
else SendClientMessage(playerid,-1,"USAGE: /timeban <playerid> <hours> <minutes> <seconds> <reason>");
return 1;
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
COMMAND:isbanned(playerid,params[])
{
/*
One and only parameter represents the name of the account/player
you want to check if it's banned or not.
*/
if(IsPlayerAdmin(playerid))
{
new name[32];
if(!sscanf(params, "s[32]", name))
{
if(IsPlayerTimeBanned(name) == 1) SendClientMessage(playerid, -1, "Player is temporarily banned.");
else if(IsPlayerTimeBanned(name) == 0) SendClientMessage(playerid, -1, "Player is not temporarily banned.");
return 1;
}
else SendClientMessage(playerid,-1,"USAGE: /isbanned <name>");
return 1;
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
COMMAND:checkban(playerid,params[])
{
/*
One and only parameter represents the name of the account/player
you want to retrieve ban info.
*/
if(IsPlayerAdmin(playerid))
{
new name[32];
if(!sscanf(params, "s[32]", name))
{
new y, mo, d, h, mi, s;
GetPlayerBanTimeInfo(playerid, y, mo, d, h, mi, s);
new str[100];
format(str, sizeof(str), "%s's ban expires on: %d.%d.%d | %d:%d:%d", name, d, mo, y, h, mi, s);
SendClientMessage(playerid, -1, str);
return 1;
}
else SendClientMessage(playerid,-1,"USAGE: /checkban <name>");
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
COMMAND:unban(playerid,params[])
{
/*
One and only parameter represents the name of the account/player
you want to unban.
*/
if(IsPlayerAdmin(playerid))
{
new name[32];
if(!sscanf(params, "s[32]", name))
{
UnbanPlayer(name);
SendClientMessage(playerid, -1, "Player is unbanned.");
return 1;
}
else SendClientMessage(playerid,-1,"USAGE: /unban <name>");
}
else SendClientMessage(playerid,-1,"ERROR: You do not have administrative rights to perform this action!");
return 1;
}
There are also 2 new callbacks and 1 new disconnect reason that this include brings!
PHP код:
forward OnPlayerTimeBanned(playerid, reason[], hours, minutes, seconds);
forward OnPlayerUnbanned(name[]);
PHP код:
public OnPlayerTimeBanned(playerid, reason[], hours, minutes, seconds)
{
new msg[256];
format(msg, sizeof(msg), "[Ban] Player %d has been time banned for %dh%dm%ds. Reason: %s", playerid, hours, minutes, seconds, reason);
print(msg);
}
public OnPlayerUnbanned(name[])
{
printf("[Unban] Account %s has been unbanned!", name);
}
PHP код:
public OnPlayerDisconnect(playerid, reason)
{
switch(reason)
{
case DC_REASON_TIMEBAN:
{
printf("[Disconnect] Player %d got time banned!", playerid);
return 1;
}
}
return 1;
}
CustomMoney.inc
This kinda new money bar supports possibly up to 8 digits, as well as protects the server from experiencing money hacks. This is a rewrite of the old, crappy, buggy, laggy, Dini-file-saving-using money include named money.inc. Now saves the money in SQL database, and saves it on disconnect instead under OnPlayerUpdate.
PHP код:
//same role as GivePlayerMoney
native GiveMoney(playerid, ammount);
//same role as GivePlayerMoney, but providing negative money ammount
native TakeMoney(playerid, ammount);
//same role as ResetPlayerMoney -> GivePlayerMoney
native SetMoney(playerid, ammount);
//same role as ResetPlayerMoney
native ResetMoney(playerid);
//same role as GetPlayerMoney
native GetMoney(playerid);
It's very simple to use, just #include it and replace those default SAMP money functions with these ones, and voila - it will work!
__________________________________________________ _______________________________________________
OnPlayerChangeAngle.inc
Separate version of the angle change detection previously found in opc.inc.
Example usage:
PHP код:
new count[MAX_PLAYERS] = 0;
public OnPlayerChangeAngle(playerid, Float:old_angle, Float:new_angle)
{
if(old_angle != new_angle) count[playerid] = 0;
else
{
count[playerid]++;
if(count[playerid] == 30) printf("Player %d hasn't changed their angle for 30 seconds!");
}
return 1;
}
__________________________________________________ _______________________________________________
OnPlayerChangePosition.inc
Separate version of the position change detection previously found in opc.inc.
Example usage:
PHP код:
new count[MAX_PLAYERS] = 0;
public OnPlayerChangePosition(playerid, Float:old_x, Float:old_y, Float:old_z, Float:new_x, Float:new_y, Float:new_z)
{
if(old_x != new_x || old_y != new_y || old_z != new_z) count[playerid] = 0;
else
{
count[playerid]++;
if(count[playerid] == 30) printf("Player %d hasn't changed their position for 30 seconds!", playerid);
}
}
__________________________________________________ _______________________________________________
Logger.inc
Small include, nothing advanced.
Allows you to log certain functions (in console + in file named "Logger.log", changeable in include file), such as:
- SendClientMessage
- SendClientMessageToAll
- GameTextForPlayer
- GameTextForAll
You can easily log more functions by adding "Log::Write" to desired place.
__________________________________________________ _______________________________________________
Outro:
I don't have an ETA of those 3 mentioned-but-not-released includes, though they will get published in near future.
If you find any bugs/problems/errors, please, do not hesitate to contact or notify me either here or anywhere else. Report them so they can get fixed fast and provide even better experience.
Furthermore, all my coding can be found on my GitHub page. Anyone who is willing to contribute and help me out, is free to do so. All suggestions and wishes are also welcome.
To download/see code for specific include, either click on links in "Content" section.
Special thanks to Zeex for his ZCMD include, ****** for sscanf, Slice for his BUD include, and of course Kalcor for SAMP!