rendered paste body/*
Alex "Y_Less" Cole's server system
- auto messages system (inc MOTD)
Messaging system, periodically sends messages to all server members
as well as specific ones on connect or spawn (MOTD style)
Based on previous messaging systems I have produced but much improved.
Features:
Messages read from file
Commands:
*/
#include <a_samp>
#include "YSScommon.pwn"
#define YS_MESSAGES_ON // Always on
//#define YS_MESSAGES_SEL // INI defined
#define SEND_MESSAGE_ALL(%1) if (gMessages[d][MS_TEXT_%1][0]) CallRemoteFunction("SendFormattedMessageToAll", "is", c, gMessages[d][MS_TEXT_%1]);
#define SEND_MESSAGE(%1) if (gMessages[d][MS_TEXT_%1][0]) CallRemoteFunction("SendFormattedMessage", "iis", playerid, c, gMessages[d][MS_TEXT_%1]);
#define YS_MAX_MESSAGES 16
#define MS_BITS_MOTD 0x000000FF
#define MS_BITS_COUNT 0x0000FF00
#define MS_BITS_MOTD_SPAWN 0x01000000
#define MS_BITS_MOTD_CONN 0x02000000
#define MS_BITS_MOTD_INC 0x04000000
#define MS_BITS_USE 0x08000000
new gMessageDat = 0xFFFFFFFF;
//new gLastMessage;
new gMessageDelay = 1500; // 5 mins
//new gMessageCount = 0;
#define MS_TYPE_IGNORE 0x00010000
#define __NONE__ group = 0;
#define YS_INI_MESSAGES 1
#define YS_INI_MEMBERLEVELS 2
#define YS_INI_COMMANDLEVELS 3
#define YS_INI_ALTNAMES 4
#define YS_INI_SETTINGS 5
#define YS_INI_IGNORECOMMANDS 6
#define YS_INI_FILTERCOMMANDS 7
#define YS_INI_LOGGING 8
enum YS_MESSAGE_DAT
{
MS_TYPE, // 0xFFFF0000 - info, 0x0000FFFF - type
MS_INFO, // Color or display time depending on MS_TYPE
MS_TEXT_0[MAX_INI_LINE],
MS_TEXT_1[MAX_INI_LINE],
MS_TEXT_2[MAX_INI_LINE],
MS_TEXT_3[MAX_INI_LINE],
MS_TEXT_4[MAX_INI_LINE]
}
new gMessages[YS_MAX_MESSAGES][YS_MESSAGE_DAT];
forward YSProcess();
forward ReadINI(update);
public OnFilterScriptInit()
{
ADD_MODULE("messages", "YSS messages module v0.1 (c) Alex \"Y_Less\" Cole")
READINI
return 1;
}
public OnFilterScriptExit()
{
REMOVE_MODULE("messages")
return 1;
}
public OnPlayerSpawn(playerid)
{
if (gMessageDat & MS_BITS_MOTD_SPAWN)
{
if ((gMessageDat & MS_BITS_MOTD) != 0xFF)
{
DisplayMessage(playerid, (gMessageDat & MS_BITS_MOTD));
}
}
}
public OnPlayerConnect(playerid)
{
if (gMessageDat & MS_BITS_MOTD_CONN)
{
if ((gMessageDat & MS_BITS_MOTD) != 0xFF)
{
DisplayMessage(playerid, (gMessageDat & MS_BITS_MOTD));
}
}
}
public YSProcess()
{
PRIORITY(gMessageDelay)
{
#if !defined YS_MESSAGES_ON
if (gMessageDat & MS_BITS_USE)
{
#endif
DisplayMessage();
#if !defined YS_MESSAGES_ON
}
#endif
}
}
DisplayMessage(playerid = INVALID_PLAYER_ID, d = 255)
{
if (d == 255)
{
do
{
d = random((gMessageDat & MS_BITS_COUNT) >>> 8);
}
while (/*d == 255 || */((gMessageDat & MS_BITS_MOTD) == d && !(gMessageDat & MS_BITS_MOTD_INC)) || (MS_TYPE_IGNORE & gMessages[d][MS_TYPE]));
}
if (playerid == INVALID_PLAYER_ID)
{
if (gMessages[d][MS_TYPE] & 0xFFFF)
{
CallRemoteFunction("GameFormattedMessageToAll", "sii", gMessages[d][MS_TEXT_0], gMessages[d][MS_INFO] * 1000, gMessages[d][MS_TYPE] & 0xFFFF);
}
else
{
new c = gMessages[d][MS_INFO];
SEND_MESSAGE_ALL(0)
SEND_MESSAGE_ALL(1)
SEND_MESSAGE_ALL(2)
SEND_MESSAGE_ALL(3)
SEND_MESSAGE_ALL(4)
}
}
else
{
if (gMessages[d][MS_TYPE] & 0xFFFF)
{
CallRemoteFunction("GameFormattedMessage", "isii", playerid, gMessages[d][MS_TEXT_0], gMessages[d][MS_INFO] * 1000, gMessages[d][MS_TYPE] & 0xFFFF);
}
else
{
new c = gMessages[d][MS_INFO];
SEND_MESSAGE(0)
SEND_MESSAGE(1)
SEND_MESSAGE(2)
SEND_MESSAGE(3)
SEND_MESSAGE(4)
}
}
}
public ReadINI(update)
{
new File:inifile;
if (fexist(INI_NAME))
{
inifile = fopen(INI_NAME, io_read);
if (inifile)
{
new mc = 0;
new intext = 0;
new str[MAX_INI_LINE];
new group = 0;
new timed = 0;
while (fread(inifile, str))
{
// Read line first
if (str[0] == '[')
{
StripNL(str);
INI_GROUP(MESSAGES)
else INI_GROUP(SETTINGS)
else __NONE__
}
else
{
switch (group)
{
case YS_INI_MESSAGES:
{
//INIT // Do multiply
if (!intext)
{
if (mc < YS_MAX_MESSAGES)
{
INI_GET_B(Ignore, MS_TYPE_IGNORE, 6, gMessages[mc][MS_TYPE])
else if (strcmp(str, "Type", true, 4) == 0)
{
gMessages[mc][MS_TYPE] &= 0xFFFF0000;
gMessages[mc][MS_TYPE] += strval(ReturnINIValue(str[4]));
}
else INI_GET_H(Color, gMessages[mc][MS_INFO], 5)
else INI_GET_I(Time, gMessages[mc][MS_INFO], 4)
else INI_GET_B(Spawn, MS_BITS_MOTD_SPAWN, 5, gMessageDat)
else INI_GET_B(Connect, MS_BITS_MOTD_CONN, 7, gMessageDat)
//else if (strcmp(str, "Connect", true, 7) == 0) { if (strval(ReturnINIValue(str[7]))) { gMessageDat &= -1 ^ MS_BITS_MOTD_TYPE; } else { gMessageDat |= MS_BITS_MOTD_TYPE; } }
//else if (strcmp(str, "Spawn", true, 5) == 0) { if (strval(ReturnINIValue(str[7]))) { gMessageDat |= MS_BITS_MOTD_TYPE; } else { gMessageDat &= -1 ^ MS_BITS_MOTD_TYPE; } }
else INI_GET_B(Include, MS_BITS_MOTD_INC, 7, gMessageDat)
else if (strcmp(str, "Motd", true, 4) == 0)
{
gMessageDat &= 0xFFFFFF00;
if (strval(ReturnINIValue(str[4])))
{
gMessageDat |= mc & 0xFF;
}
else
{
gMessageDat |= 0xFF;
}
}
else if (strcmp(str, "Text", true, 4) == 0)
{
intext = 1;
}
}
else
{
print("YSS warning: Max messages reached");
intext = -1;
}
}
else if (intext > 0)
{
if (str[0] > 0x20)
{
StripNL(str);
switch (intext)
{
case 1:
{
format(gMessages[mc][MS_TEXT_0], MAX_INI_LINE, "%s", str);
}
case 2:
{
format(gMessages[mc][MS_TEXT_1], MAX_INI_LINE, "%s", str);
}
case 3:
{
format(gMessages[mc][MS_TEXT_2], MAX_INI_LINE, "%s", str);
}
case 4:
{
format(gMessages[mc][MS_TEXT_3], MAX_INI_LINE, "%s", str);
}
case 5:
{
format(gMessages[mc][MS_TEXT_4], MAX_INI_LINE, "%s", str);
}
default:
{
intext = -1;
}
}
intext++;
}
else
{
intext = 0;
mc++;
}
}
}
case YS_INI_SETTINGS:
{
INIT
INI_GET_B(UseMessages, MS_BITS_USE, 11, gMessageDat)
else if (strcmp(str, "MessageDelay", true, 12) == 0)
{
gMessageDelay = strval(ReturnINIValue(str[12]));
timed = 1;
}
}
}
}
}
gMessageDat &= 0xFFFF00FF;
new c;
for (new i = 0; i < YS_MAX_MESSAGES; i++)
{
if (gMessages[i][MS_TEXT_0][0] != 0)
{
c++;
}
}
gMessageDat |= (c << 8) & MS_BITS_COUNT;
if (timed)
{
gMessageDelay /= PROCESS_LOOP_DELAY; // Account for the calling frequency
}
}
else
{
print("YSS warning: Could not read ini file, default settings loaded");
}
}
else
{
print("YSS warning: Could not find ini file, default settings loaded");
}
}
hexval(string[])
{
new m = 0;
if (string[0] == '0' && string[1] == 'x') m = 2;
new ret = 0;
for (new i = m, j = 28; i < 8 + m; i++, j -= 4)
{
new k = string[i];
if (k >= '0' && k <= '9')
{
ret += (k - 0x30) << j;
}
else if (k >= 'A' && k <= 'F')
{
ret += (k - 0x37) << j;
}
else if (k >= 'a' && k <= 'f')
{
ret += (k - 0x57) << j;
}
else
{
return 0;
}
}
return ret;
}