1 // teamflagreset.cpp : Defines the entry point for the DLL application.
2 
3 #include "bzfsAPI.h"
4 
5 // event handler callback
6 
7 class TFR
8 {
9 public:
TFR()10     TFR()
11     {
12         idleTime = 300;
13         redLastTouched = bz_getCurrentTime();
14         greenLastTouched = bz_getCurrentTime();
15         blueLastTouched = bz_getCurrentTime();
16         purpleLastTouched = bz_getCurrentTime();
17         redFlagWasHeld = false;
18         greenFlagWasHeld = false;
19         blueFlagWasHeld = false;
20         purpleFlagWasHeld = false;
21         OKToReset = false;
22         timerOff = false;
23         flagTouched ="";
24     }
25     double idleTime;
26     double redLastTouched;
27     double greenLastTouched;
28     double blueLastTouched;
29     double purpleLastTouched;
30     bool redFlagWasHeld;
31     bool greenFlagWasHeld;
32     bool blueFlagWasHeld;
33     bool purpleFlagWasHeld;
34     bool OKToReset;
35     bool timerOff;
36     const char* flagTouched;
37 };
38 
39 TFR tfr;
40 
41 class TeamFlagResetHandler : public bz_Plugin
42 {
43 public:
Name()44     virtual const char* Name ()
45     {
46         return "Team Flag Reset";
47     }
48     virtual void Init ( const char* config );
49     virtual void Cleanup ();
50     virtual void Event ( bz_EventData *eventData );
51 };
52 
53 class TeamFlagResetIOHandler : public bz_CustomSlashCommandHandler
54 {
55 public:
~TeamFlagResetIOHandler()56     virtual ~TeamFlagResetIOHandler() {};
57     virtual bool SlashCommand ( int playerID, bz_ApiString command, bz_ApiString message, bz_APIStringList *param );
58 };
59 
60 BZ_PLUGIN(TeamFlagResetHandler)
61 TeamFlagResetIOHandler  teamflagresetiohandler;
62 
ConvertToInteger(std::string msg)63 double ConvertToInteger(std::string msg)
64 {
65 
66     int msglength = (int)msg.length();
67 
68     if (msglength > 0 && msglength < 4)
69     {
70 
71         double msgvalue = 0;
72         double tens = 1;
73 
74         for ( int i = (msglength - 1); i >= 0; i-- )
75         {
76 
77             if (msg[i] < '0' || msg[i] > '9')  // got something other than a number
78                 return 0;
79 
80             tens *= 10;
81             msgvalue +=  (((double)msg[i] - '0') / 10) * tens;
82 
83         }
84 
85         // we're ok so far, check limits:
86 
87         if (msgvalue >= 1 && msgvalue <= 120)
88             return msgvalue;
89 
90     }
91     return 0;
92 }
93 
Init(const char * commandLineParameter)94 void TeamFlagResetHandler::Init ( const char* commandLineParameter )
95 {
96     std::string param = commandLineParameter;
97     double timelimitparam = ConvertToInteger(param);
98 
99     if (timelimitparam > 0)
100         tfr.idleTime = timelimitparam * 60;
101 
102     Register(bz_eTickEvent);
103     bz_registerCustomSlashCommand("tfrtime",&teamflagresetiohandler);
104     bz_registerCustomSlashCommand("tfroff",&teamflagresetiohandler);
105     bz_registerCustomSlashCommand("tfron",&teamflagresetiohandler);
106     bz_registerCustomSlashCommand("tfrstatus",&teamflagresetiohandler);
107 }
108 
Cleanup(void)109 void TeamFlagResetHandler::Cleanup ( void )
110 {
111     Flush();
112     bz_removeCustomSlashCommand("tfrtime");
113     bz_removeCustomSlashCommand("tfroff");
114     bz_removeCustomSlashCommand("tfron");
115     bz_removeCustomSlashCommand("tfrstatus");
116 }
117 
ResetFlagData()118 void ResetFlagData()
119 {
120 
121     tfr.redLastTouched = bz_getCurrentTime();
122     tfr.greenLastTouched = bz_getCurrentTime();
123     tfr.blueLastTouched = bz_getCurrentTime();
124     tfr.purpleLastTouched = bz_getCurrentTime();
125     tfr.redFlagWasHeld = false;
126     tfr.greenFlagWasHeld = false;
127     tfr.blueFlagWasHeld = false;
128     tfr.purpleFlagWasHeld = false;
129 
130 }
131 
resetTeamFlag(bz_ApiString flagSent)132 void resetTeamFlag (bz_ApiString flagSent)
133 {
134     for ( unsigned int i = 0; i < bz_getNumFlags(); i++ )
135     {
136         if (flagSent == bz_getFlagName(i))
137             bz_resetFlag (i);
138     }
139 }
140 
Event(bz_EventData * eventData)141 void TeamFlagResetHandler::Event ( bz_EventData *eventData )
142 {
143     if (eventData->eventType != bz_eTickEvent)
144         return;
145 
146     if (tfr.timerOff == true)
147         return;
148 
149     bz_APIIntList *playerList = bz_newIntList();
150     bz_getPlayerIndexList ( playerList );
151 
152     // check to see if anyone has picked up a team flag & count players per team
153 
154     for ( unsigned int i = 0; i < playerList->size(); i++ )
155     {
156 
157         bz_BasePlayerRecord *player = bz_getPlayerByIndex(playerList->operator[](i));
158 
159         if (player)
160         {
161 
162             tfr.flagTouched = bz_getPlayerFlag(player->playerID);
163 
164             if (tfr.flagTouched)
165             {
166 
167                 if (strcmp(tfr.flagTouched, "R*") == 0)
168                 {
169                     tfr.redLastTouched = bz_getCurrentTime();
170                     tfr.redFlagWasHeld = true;
171                 }
172                 if (strcmp(tfr.flagTouched, "G*") == 0)
173                 {
174                     tfr.greenLastTouched = bz_getCurrentTime();
175                     tfr.greenFlagWasHeld = true;
176                 }
177                 if (strcmp(tfr.flagTouched, "B*") == 0)
178                 {
179                     tfr.blueLastTouched = bz_getCurrentTime();
180                     tfr.blueFlagWasHeld = true;
181                 }
182                 if (strcmp(tfr.flagTouched, "P*") == 0)
183                 {
184                     tfr.purpleLastTouched = bz_getCurrentTime();
185                     tfr.purpleFlagWasHeld = true;
186                 }
187             }
188 
189             bz_freePlayerRecord(player);
190         }
191     }
192 
193     bz_deleteIntList(playerList);
194 
195     // if no teamplay, no need to reset flags
196 
197     tfr.OKToReset = false;
198 
199     if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(eGreenTeam) > 0)
200         tfr.OKToReset = true;
201     if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(eBlueTeam) > 0)
202         tfr.OKToReset = true;
203     if (bz_getTeamCount(eRedTeam) * bz_getTeamCount(ePurpleTeam) > 0)
204         tfr.OKToReset = true;
205     if (bz_getTeamCount(eGreenTeam) * bz_getTeamCount(eBlueTeam) > 0)
206         tfr.OKToReset = true;
207     if (bz_getTeamCount(eGreenTeam) * bz_getTeamCount(ePurpleTeam) > 0)
208         tfr.OKToReset = true;
209     if (bz_getTeamCount(eBlueTeam) * bz_getTeamCount(ePurpleTeam) > 0)
210         tfr.OKToReset = true;
211 
212     if (tfr.OKToReset == false)
213     {
214         ResetFlagData();
215         return;
216     }
217 
218     // check if time's up on flags and reset (if they were held at least once after last reset)
219 
220     if (bz_getCurrentTime() - tfr.redLastTouched > tfr.idleTime && tfr.redFlagWasHeld)
221     {
222         if (bz_getTeamCount(eRedTeam) > 0)
223         {
224             resetTeamFlag ("R*");
225             bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Red flag sat idle too long - reset by server.");
226         }
227         tfr.redFlagWasHeld = false;
228         tfr.redLastTouched = bz_getCurrentTime();
229     }
230 
231     if (bz_getCurrentTime() - tfr.greenLastTouched > tfr.idleTime && tfr.greenFlagWasHeld)
232     {
233         if (bz_getTeamCount(eGreenTeam) > 0)
234         {
235             resetTeamFlag ("G*");
236             bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Green flag sat idle too long - reset by server.");
237         }
238         tfr.greenLastTouched = bz_getCurrentTime();
239         tfr.greenFlagWasHeld = false;
240     }
241 
242     if (bz_getCurrentTime() - tfr.blueLastTouched > tfr.idleTime && tfr.blueFlagWasHeld)
243     {
244         if (bz_getTeamCount(eBlueTeam) > 0)
245         {
246             resetTeamFlag ("B*");
247             bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Blue flag sat idle too long - reset by server.");
248         }
249         tfr.blueLastTouched = bz_getCurrentTime();
250         tfr.blueFlagWasHeld = false;
251     }
252 
253     if (bz_getCurrentTime() - tfr.purpleLastTouched > tfr.idleTime && tfr.purpleFlagWasHeld)
254     {
255         if (bz_getTeamCount(ePurpleTeam) > 0)
256         {
257             resetTeamFlag ("P*");
258             bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Purple flag sat idle too long - reset by server.");
259         }
260         tfr.purpleLastTouched = bz_getCurrentTime();
261         tfr.purpleFlagWasHeld = false;
262     }
263     return;
264 }
265 
SlashCommand(int playerID,bz_ApiString _command,bz_ApiString _message,bz_APIStringList *)266 bool TeamFlagResetIOHandler::SlashCommand ( int playerID, bz_ApiString _command, bz_ApiString _message,
267         bz_APIStringList * /*_param*/ )
268 {
269     std::string command = _command.c_str();
270     std::string message = _message.c_str();
271 
272     bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(playerID);
273 
274     if (fromPlayer)
275     {
276         if (!fromPlayer->admin)
277         {
278             bz_sendTextMessage(BZ_SERVER,playerID,"You must be admin to use the teamflagreset commands.");
279             bz_freePlayerRecord(fromPlayer);
280             return true;
281         }
282         bz_freePlayerRecord(fromPlayer);
283     }
284 
285     if ( command == "tfrtime")
286     {
287 
288         double invalue = ConvertToInteger(message);
289 
290         if (invalue > 0)
291         {
292 
293             tfr.timerOff = false;
294             tfr.idleTime = invalue * 60;
295 
296             int AdjTime = (int)(tfr.idleTime / 60 + 0.5);
297             bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Team flag idle time has been set to %i minutes.", AdjTime);
298 
299             ResetFlagData();
300             return true;
301         }
302         else
303         {
304             bz_sendTextMessagef (BZ_SERVER, playerID, "Team flag idle time invalid: must be between 1 and 120 minutes.");
305             return true;
306         }
307         return true;
308     }
309 
310     if ( command == "tfroff")
311     {
312 
313         tfr.timerOff = true;
314         bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Team flag reset is disabled.");
315         return true;
316     }
317 
318     if ( command == "tfron")
319     {
320 
321         tfr.timerOff = false;
322         ResetFlagData();
323         bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "Team flag reset is enabled.");
324         return true;
325     }
326 
327     if ( command == "tfrstatus")
328     {
329 
330         if (tfr.timerOff)
331             bz_sendTextMessagef (BZ_SERVER, playerID, "Team flag reset is disabled.");
332         else
333             bz_sendTextMessagef (BZ_SERVER, playerID, "Team flag reset is enabled.");
334 
335         int AdjTime = (int)(tfr.idleTime / 60 + 0.5);
336         bz_sendTextMessagef (BZ_SERVER, playerID, "Team flag idle time is: %i minutes.", AdjTime);
337 
338         return true;
339     }
340 
341     return false;
342 }
343 
344 // Local Variables: ***
345 // mode: C++ ***
346 // tab-width: 4 ***
347 // c-basic-offset: 4 ***
348 // indent-tabs-mode: nil ***
349 // End: ***
350 // ex: shiftwidth=4 tabstop=4
351