/* 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 #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; }