1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 /* interface header */
14 #include "BZAdminClient.h"
15 
16 /* system implementation headers */
17 #ifdef HAVE_CMATH
18 #  include <cmath>
19 #else
20 #  include <math.h>
21 #endif
22 #include <stdio.h>
23 #include <string.h>
24 #include <iostream>
25 #include <sstream>
26 
27 /* common implementation headers */
28 #include "BZAdminUI.h"
29 #include "StateDatabase.h"
30 #include "TextUtils.h"
31 #include "version.h"
32 #include "Team.h"
33 #include "ServerList.h"
34 #include "ErrorHandler.h"
35 #include "cURLManager.h"
36 #include "TimeKeeper.h"
37 
38 StartupInfo startupInfo;
39 
BZAdminClient(BZAdminUI * bzInterface)40 BZAdminClient::BZAdminClient(BZAdminUI* bzInterface)
41     : myTeam(ObserverTeam), sLink(Address(startupInfo.serverName), startupInfo.serverPort), valid(false), ui(bzInterface)
42 {
43 
44     if (sLink.getState() != ServerLink::Okay)
45     {
46         switch (sLink.getState())
47         {
48         case ServerLink::BadVersion:
49         {
50             std::cout << "Incompatible server version " << sLink.getVersion();
51             break;
52         }
53         case ServerLink::Refused:
54         {
55             std::string banMessage = "Server Refused connection due to ban: ";
56             banMessage += sLink.getRejectionMessage();
57             std::cout << banMessage;
58             break;
59         }
60         case ServerLink::Rejected:
61             std::cout << "Game is full or over.  Try again later.";
62             break;
63         case ServerLink::SocketError:
64             std::cout << "Error connecting to server.";
65             break;
66         case ServerLink::CrippledVersion:
67             std::cout << "Cannot connect to full version server.";
68             break;
69         default:
70             std::cout << "Internal error connecting to server.";
71             break;
72         }
73         std::cout << std::endl;
74         return;
75     }
76     if ((startupInfo.token[0] == '\0') && (startupInfo.password[0] != '\0'))
77     {
78         // won't really output anything, just gets token
79         outputServerList();
80     }
81     sLink.sendEnter(TankPlayer, myTeam, startupInfo.callsign, "bzadmin", startupInfo.token);
82     if (sLink.getState() != ServerLink::Okay)
83     {
84         std::cerr << "Rejected." << std::endl;
85         return;
86     }
87 
88     std::string reason;
89     uint16_t code, rejcode;
90     if (sLink.readEnter (reason, code, rejcode))
91         valid = true;
92     else
93         std::cerr << reason << std::endl;
94 
95 
96     // tell BZDB to shut up, we can't have debug data printed to stdout
97     BZDB.setDebug(false);
98 
99     // set a default message mask
100     showMessageType(MsgAddPlayer);
101     showMessageType(MsgAdminInfo);
102     showMessageType(MsgKilled);
103     showMessageType(MsgMessage);
104     showMessageType(MsgNewRabbit);
105     showMessageType(MsgPause);
106     showMessageType(MsgRemovePlayer);
107     showMessageType(MsgSuperKill);
108 
109     // initialise the colormap
110     colorMap[NoTeam] = Yellow;
111     colorMap[RogueTeam] = Yellow;
112     colorMap[RedTeam] = Red;
113     colorMap[GreenTeam] = Green;
114     colorMap[BlueTeam] = Blue;
115     colorMap[PurpleTeam] = Purple;
116     colorMap[ObserverTeam] = Cyan;
117 
118     // initialise the msg type map
119     // FIXME MsgPlayerInfo
120     msgTypeMap["bzdb"] = MsgSetVar;
121     msgTypeMap["chat"] = MsgMessage;
122     msgTypeMap["admin"] = MsgAdminInfo;
123     msgTypeMap["join"] = MsgAddPlayer;
124     msgTypeMap["kill"] = MsgKilled;
125     msgTypeMap["leave"] = MsgRemovePlayer;
126     msgTypeMap["pause"] = MsgPause;
127     msgTypeMap["ping"] = MsgLagPing;
128     msgTypeMap["rabbit"] = MsgNewRabbit;
129     msgTypeMap["score"] = MsgScore;
130     msgTypeMap["spawn"] = MsgAlive;
131     msgTypeMap["time"] = MsgTimeUpdate;
132     msgTypeMap["over"] = MsgScoreOver;
133 }
134 
135 
getMyId()136 PlayerId BZAdminClient::getMyId()
137 {
138     return sLink.getId();
139 }
140 
141 
checkMessage()142 BZAdminClient::ServerCode BZAdminClient::checkMessage()
143 {
144     uint16_t code, len;
145     char inbuf[MaxPacketLen];
146     PlayerIdMap::iterator iter;
147 
148     // read until we have a package, or until we have waited 100 ms
149     if (sLink.read(code, len, inbuf, 100) == 1)
150     {
151         lastMessage.first = "";
152         lastMessage.second = Default;
153         const void* vbuf = inbuf;
154         PlayerId p;
155         PlayerIdMap::const_iterator it;
156         std::string victimName, killerName;
157         Address a;
158 
159         switch (code)
160         {
161 
162         case MsgNewRabbit:
163             if (messageMask[MsgNewRabbit])
164             {
165                 vbuf = nboUnpackUByte(vbuf, p);
166                 if (p != NoPlayer)
167                     lastMessage.first = std::string("*** '") + players[p].name +
168                                         "' is now the rabbit.";
169             }
170             break;
171 
172         case MsgPause:
173             if (messageMask[MsgPause])
174             {
175                 uint8_t paused;
176                 vbuf = nboUnpackUByte(vbuf, p);
177                 vbuf = nboUnpackUByte(vbuf, paused);
178                 lastMessage.first = std::string("*** '") + players[p].name + "': " +
179                                     (paused ? "paused" : "resumed") + ".";
180             }
181             break;
182 
183         case MsgAlive:
184             if (messageMask[MsgAlive])
185             {
186                 vbuf = nboUnpackUByte(vbuf, p);
187                 lastMessage.first = std::string("*** '") + players[p].name +
188                                     "' has respawned.";
189             }
190             break;
191 
192         case MsgLagPing:
193             if (messageMask[MsgLagPing])
194                 lastMessage.first = "*** Received lag ping from server.";
195             break;
196 
197         case MsgSetVar:
198             // code stolen from playing.cxx
199             uint16_t numVars;
200             uint8_t nameLen, valueLen;
201 
202             // Flawfinder: ignore
203             char name[MaxPacketLen];
204             // Flawfinder: ignore
205             char value[MaxPacketLen];
206             int i;
207 
208             vbuf = nboUnpackUShort(vbuf, numVars);
209             for (i = 0; i < numVars; i++)
210             {
211                 vbuf = nboUnpackUByte(vbuf, nameLen);
212                 vbuf = nboUnpackString(vbuf, name, nameLen);
213                 name[nameLen] = '\0';
214 
215                 vbuf = nboUnpackUByte(vbuf, valueLen);
216                 vbuf = nboUnpackString(vbuf, value, valueLen);
217                 value[valueLen] = '\0';
218 
219                 BZDB.set(name, value);
220                 BZDB.setPersistent(name, false);
221                 BZDB.setPermission(name, StateDatabase::Locked);
222             }
223             if (messageMask[MsgSetVar])
224             {
225                 lastMessage.first = std::string("*** Received BZDB update, ") +
226                                     TextUtils::format("%d", numVars) + " variable" +
227                                     (numVars == 1 ? "" : "s") + " updated.";
228             }
229             break;
230 
231         case MsgAddPlayer:
232             uint16_t team, type, wins, losses, tks;
233             // Flawfinder: ignore
234             char callsign[CallSignLen];
235             // Flawfinder: ignore
236             char motto[MottoLen];
237             vbuf = nboUnpackUByte(vbuf, p);
238             vbuf = nboUnpackUShort(vbuf, type);
239             vbuf = nboUnpackUShort(vbuf, team);
240             vbuf = nboUnpackUShort(vbuf, wins);
241             vbuf = nboUnpackUShort(vbuf, losses);
242             vbuf = nboUnpackUShort(vbuf, tks);
243             vbuf = nboUnpackString(vbuf, callsign, CallSignLen);
244             vbuf = nboUnpackString(vbuf, motto, MottoLen);
245             players[p].name = callsign;
246             players[p].team = TeamColor(team);
247             players[p].wins = wins;
248             players[p].losses = losses;
249             players[p].tks = tks;
250             players[p].isRegistered = false;
251             players[p].isVerified = false;
252             players[p].isAdmin = false;
253             if (ui != NULL)
254                 ui->addedPlayer(p);
255             // If you are an admin, then MsgAdminInfo will output the message
256             if (messageMask[MsgAddPlayer] && !players[getMyId()].isAdmin)
257             {
258                 Team temp;
259                 std::string joinMsg = std::string("*** \'") + callsign + "\' joined the game as " +
260                                       temp.getName(players[p].team) + ".";
261                 lastMessage.first = joinMsg;
262             }
263             break;
264 
265         case MsgRemovePlayer:
266             vbuf = nboUnpackUByte(vbuf, p);
267             if (ui != NULL)
268                 ui->removingPlayer(p);
269             if (messageMask[MsgRemovePlayer])
270             {
271                 lastMessage.first = std::string("*** '") + players[p].name +
272                                     "' left the game.";
273             }
274             players.erase(p);
275             break;
276 
277         case MsgPlayerInfo:
278             uint8_t numPlayers;
279             vbuf = nboUnpackUByte(vbuf, numPlayers);
280             for (i = 0; i < numPlayers; ++i)
281             {
282                 vbuf = nboUnpackUByte(vbuf, p);
283                 uint8_t info;
284                 // parse player info bitfield
285                 vbuf = nboUnpackUByte(vbuf, info);
286                 players[p].isAdmin = ((info & IsAdmin) != 0);
287                 players[p].isRegistered = ((info & IsRegistered) != 0);
288                 players[p].isVerified = ((info & IsVerified) != 0);
289             }
290             break;
291 
292         case MsgAdminInfo:
293             uint8_t numIPs;
294             uint8_t tmp;
295             vbuf = nboUnpackUByte(vbuf, numIPs);
296             if (numIPs > 1)
297             {
298                 for (i = 0; i < numIPs; ++i)
299                 {
300                     vbuf = nboUnpackUByte(vbuf, tmp);
301                     vbuf = nboUnpackUByte(vbuf, p);
302                     vbuf = a.unpack(vbuf);
303                     players[p].ip = a.getDotNotation();
304                     if ((ui != NULL) && messageMask[MsgAdminInfo])
305                     {
306                         ui->outputMessage("*** IPINFO: " + players[p].name + " from "  +
307                                           players[p].ip, Default);
308                     }
309                 }
310             }
311             //Alternative to the MsgAddPlayer message
312             else if (numIPs == 1)
313             {
314                 vbuf = nboUnpackUByte(vbuf, tmp);
315                 vbuf = nboUnpackUByte(vbuf, p);
316                 vbuf = a.unpack(vbuf);
317                 players[p].ip = a.getDotNotation();
318                 Team temp;
319                 if (messageMask[MsgAdminInfo])
320                 {
321                     std::string joinMsg = std::string("*** \'") + players[p].name + "\' joined the game as " +
322                                           temp.getName(players[p].team) + " from " + players[p].ip + ".";
323                     lastMessage.first = joinMsg;
324                 }
325             }
326             break;
327 
328         case MsgScoreOver:
329             if (messageMask[MsgScoreOver])
330             {
331                 PlayerId id;
332                 uint16_t _team;
333                 vbuf = nboUnpackUByte(vbuf, id);
334                 vbuf = nboUnpackUShort(vbuf, _team);
335                 it = players.find(id);
336                 victimName = (it != players.end() ? it->second.name : "<unknown>");
337                 if (_team != (uint16_t)NoTeam)
338                 {
339                     Team temp;
340                     victimName = temp.getName((TeamColor)_team);
341                 }
342                 lastMessage.first = std::string("*** \'") + victimName + "\' won the game.";
343             }
344             break;
345 
346         case MsgTimeUpdate:
347             if (messageMask[MsgTimeUpdate])
348             {
349                 uint32_t timeLeft;
350                 vbuf = nboUnpackUInt(vbuf, timeLeft);
351                 if (timeLeft == 0)
352                     lastMessage.first = "*** Time Expired.";
353                 else if (timeLeft == ~0u)
354                     lastMessage.first = "*** Paused.";
355                 else
356                     lastMessage.first = std::string("*** ") +
357                                         TextUtils::format("%u", timeLeft) + " seconds remaining.";
358             }
359             break;
360 
361         case MsgKilled:
362             if (messageMask[MsgKilled])
363             {
364                 PlayerId victim, killer;
365                 FlagType* flagType;
366                 int16_t shotId, reason;
367                 vbuf = nboUnpackUByte(vbuf, victim);
368                 vbuf = nboUnpackUByte(vbuf, killer);
369                 vbuf = nboUnpackShort(vbuf, reason);
370                 vbuf = nboUnpackShort(vbuf, shotId);
371                 vbuf = FlagType::unpack(vbuf, flagType);
372                 if (reason == PhysicsDriverDeath)
373                 {
374                     int32_t inPhyDrv;
375                     vbuf = nboUnpackInt(vbuf, inPhyDrv);
376                 }
377 
378                 // find the player names and build a kill message string
379                 it = players.find(victim);
380                 victimName = (it != players.end() ? it->second.name : "<unknown>");
381                 it = players.find(killer);
382                 killerName = (it != players.end() ? it->second.name : "<unknown>");
383                 lastMessage.first = std::string("*** ") + "'" + victimName + "' ";
384                 if (killer == victim)
385                     lastMessage.first = lastMessage.first + "blew myself up.";
386                 else
387                 {
388                     lastMessage.first = lastMessage.first + "destroyed by '" +
389                                         killerName + "'.";
390                 }
391             }
392             break;
393 
394         case MsgSuperKill:
395             return Superkilled;
396 
397         case MsgScore:
398             uint8_t numScores;
399             vbuf = nboUnpackUByte(vbuf, numScores);
400             for (i = 0; i < numScores; i++)
401             {
402                 uint16_t winners, loosers, teamkillers;
403                 vbuf = nboUnpackUByte(vbuf, p);
404                 vbuf = nboUnpackUShort(vbuf, winners);
405                 vbuf = nboUnpackUShort(vbuf, loosers);
406                 vbuf = nboUnpackUShort(vbuf, teamkillers);
407                 if ((iter = players.find(p)) != players.end())
408                 {
409                     iter->second.wins   = winners;
410                     iter->second.losses = loosers;
411                     iter->second.tks    = teamkillers;
412                 }
413             }
414             if (messageMask[MsgScore])
415             {
416                 lastMessage.first =
417                     std::string("*** Received score update, score for ")+
418                     TextUtils::format("%d", numScores) + " player" +
419                     (numScores == 1 ? "s" : "") + " updated.";
420             }
421             break;
422 
423         case MsgMessage:
424 
425             // unpack the message header
426             PlayerId src;
427             PlayerId dst;
428             uint8_t mtype;
429             PlayerId me = sLink.getId();
430             vbuf = nboUnpackUByte(vbuf, src);
431             vbuf = nboUnpackUByte(vbuf, dst);
432             vbuf = nboUnpackUByte(vbuf, mtype);
433 
434             // Only bother processing the message if we know how to handle it
435             if (MessageType(mtype) != ChatMessage && MessageType(mtype) != ActionMessage)
436                 break;
437 
438             // format the message depending on src and dst
439             TeamColor dstTeam = (LastRealPlayer < dst && dst <= FirstTeam ?
440                                  TeamColor(FirstTeam - dst) : NoTeam);
441             if (messageMask[MsgMessage])
442             {
443                 lastMessage.first = formatMessage((const char*)vbuf, MessageType(mtype),
444                                                   src, dst, dstTeam, me);
445                 PlayerIdMap::const_iterator iterator = players.find(src);
446                 lastMessage.second = (iterator == players.end() ?
447                                       colorMap[NoTeam] :
448                                       colorMap[iterator->second.team]);
449             }
450             break;
451         }
452         if (ui != NULL)
453             ui->handleNewPacket(code);
454         return GotMessage;
455     }
456 
457     if (sLink.getState() != ServerLink::Okay)
458     {
459         if (ui != NULL)
460             ui->outputMessage("--- ERROR: Communication error", Red);
461         return CommError;
462     }
463 
464     return NoMessage;
465 }
466 
467 
getLastMessage() const468 std::pair<std::string, ColorCode> BZAdminClient::getLastMessage() const
469 {
470     return lastMessage;
471 }
472 
473 
getPlayers()474 PlayerIdMap& BZAdminClient::getPlayers()
475 {
476     return players;
477 }
478 
479 
isValid() const480 bool BZAdminClient::isValid() const
481 {
482     return valid;
483 }
484 
outputServerList() const485 void BZAdminClient::outputServerList() const
486 {
487     if (ui)
488         ui->outputMessage(std::string("Server List:"), Yellow);
489     ServerList serverList;
490 
491     serverList.startServerPings(&startupInfo);
492 
493     // wait no more than 20 seconds for the list server
494     for (int i = 0; i < 20; i++)
495     {
496         if (!serverList.searchActive() && serverList.serverFound())
497             break;
498         if (ui)
499         {
500             if (!serverList.serverFound())
501                 ui->outputMessage(std::string("...waiting on the list server..."), Yellow);
502             else
503                 ui->outputMessage(TextUtils::format("...retrieving list of servers... (found %zu)", serverList.size()), Yellow);
504         }
505         serverList.checkEchos(&startupInfo);
506         cURLManager::perform();
507         TimeKeeper::sleep(1.0);
508     }
509     // what is your final answer?
510     serverList.checkEchos(&startupInfo);
511 
512     if (ui)
513     {
514         std::vector<ServerItem> servers = serverList.getServers();
515         for (std::vector<ServerItem>::const_iterator server = servers.begin();
516                 server != servers.end();
517                 ++server)
518             ui->outputMessage(std::string("  ") + server->description, Yellow);
519         ui->outputMessage(std::string("End Server List."), Yellow);
520     }
521 
522     return;
523 }
524 
runLoop()525 void BZAdminClient::runLoop()
526 {
527     std::string cmd;
528     ServerCode what(NoMessage);
529     while (true)
530     {
531         what = checkMessage();
532         if (what == Superkilled || what == CommError)
533             break;
534         if (ui != NULL && ui->checkCommand(cmd))
535         {
536             if (cmd == "/quit")
537                 break;
538             else if (cmd.substr(0, 6) == "/show ")
539             {
540                 if (msgTypeMap.find(cmd.substr(6)) == msgTypeMap.end())
541                 {
542                     ui->outputMessage(std::string("--- ERROR: ") + cmd.substr(6) +
543                                       " is an unknown message type", Red);
544                 }
545                 else
546                 {
547                     showMessageType(cmd.substr(6));
548                     ui->outputMessage(std::string("--- Will now show messages of the ")
549                                       + "type " + cmd.substr(6), Yellow);
550                 }
551             }
552             else if (cmd.substr(0, 6) == "/hide ")
553             {
554                 if (msgTypeMap.find(cmd.substr(6)) == msgTypeMap.end())
555                 {
556                     ui->outputMessage(std::string("--- ERROR: ") + cmd.substr(6) +
557                                       " is an unknown message type", Red);
558                 }
559                 else
560                 {
561                     ignoreMessageType(cmd.substr(6));
562                     ui->outputMessage(std::string("--- Will now hide messages of the ")
563                                       + "type " + cmd.substr(6), Yellow);
564                 }
565             }
566             else if (cmd == "/list")
567                 outputServerList();
568             else if (cmd != "")
569                 sendMessage(cmd, ui->getTarget());
570         }
571     }
572 
573     // why did we leave the loop?
574     switch (what)
575     {
576     case Superkilled:
577         lastMessage.first = "--- ERROR: Server forced disconnect";
578         lastMessage.second = Red;
579         break;
580     case CommError:
581         lastMessage.first = "--- ERROR: Connection to server lost";
582         lastMessage.second = Red;
583         break;
584     default:
585         waitForServer();
586     }
587 }
588 
589 
sendMessage(const std::string & msg,PlayerId target)590 void BZAdminClient::sendMessage(const std::string& msg,
591                                 PlayerId target)
592 {
593     // local commands:
594     // /set lists all BZDB variables
595     if (msg == "/set")
596     {
597         if (ui != NULL)
598             BZDB.iterate(listSetVars, this);
599         return;
600     }
601 
602     // Flawfinder: ignore
603     char buffer[MessageLen];
604     // Flawfinder: ignore
605     char buffer2[1 + MessageLen];
606     void* buf = buffer2;
607 
608     buf = nboPackUByte(buf, target);
609     // Flawfinder: ignore
610     strncpy(buffer, msg.c_str(), MessageLen - 1);
611     buffer[MessageLen - 1] = '\0';
612     nboPackString(buffer2 + 1, buffer, MessageLen);
613     sLink.send(MsgMessage, sizeof(buffer2), buffer2);
614 }
615 
616 
formatMessage(const std::string & msg,const MessageType type,PlayerId src,PlayerId dst,TeamColor dstTeam,PlayerId me)617 std::string BZAdminClient::formatMessage(const std::string& msg,
618         const MessageType type, PlayerId src,
619         PlayerId dst, TeamColor dstTeam,
620         PlayerId me)
621 {
622     std::string formatted = "    ";
623 
624     // get sender and receiver
625     const std::string srcName = (src == ServerPlayer ? "SERVER" :
626                                  (players.count(src) ? players[src].name :
627                                   "(UNKNOWN)"));
628     const std::string dstName = (players.count(dst) ? players[dst].name :
629                                  "(UNKNOWN)");
630 
631     // direct message to or from me
632     if (dst == me || players.count(dst))
633     {
634         if (!(src == me && dst == me))
635         {
636             if (src == me)
637             {
638                 if (type == ActionMessage)
639                     formatted += "[->" + dstName + "][" + srcName + " " + msg + "]";
640                 else
641                     formatted += "[->" + dstName + "] " + msg;
642             }
643             else
644             {
645                 if (type == ActionMessage)
646                     formatted += "[" + srcName + " " + msg + "]";
647                 else
648                     formatted += "[" + srcName + "->] " + msg;
649             }
650         }
651         else
652             formatted += msg;
653     }
654 
655     // public or admin or team message
656     else
657     {
658         if (dst == AdminPlayers)
659             formatted += "[Admin] ";
660         else if (dstTeam != NoTeam)
661             formatted += "[Team] ";
662 
663         formatted += srcName;
664         if (type != ActionMessage)
665             formatted += ":";
666         formatted += " ";
667         formatted += msg;
668     }
669 
670     return formatted;
671 }
672 
673 
setUI(BZAdminUI * bzInterface)674 void BZAdminClient::setUI(BZAdminUI* bzInterface)
675 {
676     ui = bzInterface;
677 }
678 
679 
waitForServer()680 void BZAdminClient::waitForServer()
681 {
682     // we need to know that the server has processed all our messages
683     // send a private message to ourself and wait for it to come back
684     // this assumes that the order of messages isn't changed along the way
685     bool tmp = messageMask[MsgMessage];
686     messageMask[MsgMessage] = true;
687     PlayerId me = sLink.getId();
688     if (sLink.getState() == ServerLink::Okay)
689     {
690         sendMessage("bzadminping", me);
691         std::string expected = formatMessage("bzadminping", ChatMessage, me, me, NoTeam, me);
692         std::string noTalk = formatMessage("We're sorry, you are not allowed to talk!", ChatMessage, ServerPlayer, me, NoTeam,
693                                            me);
694         BZAdminUI* tmpUI = ui;
695         ui = NULL;
696         do
697         {
698             checkMessage();
699         }
700         while (lastMessage.first != expected && lastMessage.first != noTalk);
701         ui = tmpUI;
702     }
703     messageMask[MsgMessage] = tmp;
704 }
705 
706 
ignoreMessageType(uint16_t type)707 void BZAdminClient::ignoreMessageType(uint16_t type)
708 {
709     messageMask[type] = false;
710 }
711 
712 
showMessageType(uint16_t type)713 void BZAdminClient::showMessageType(uint16_t type)
714 {
715     messageMask[type] = true;
716 }
717 
718 
ignoreMessageType(std::string type)719 void BZAdminClient::ignoreMessageType(std::string type)
720 {
721     ignoreMessageType(msgTypeMap[type]);
722 }
723 
724 
showMessageType(std::string type)725 void BZAdminClient::showMessageType(std::string type)
726 {
727     showMessageType(msgTypeMap[type]);
728 }
729 
730 
listSetVars(const std::string & name,void * thisObject)731 void BZAdminClient::listSetVars(const std::string& name, void* thisObject)
732 {
733     //Flawfinder: ignore
734     char message[MessageLen];
735     if (BZDB.getPermission(name) == StateDatabase::Locked)
736     {
737         // Flawfinder: ignore
738         snprintf(message, sizeof(message), "/set %s %f", name.c_str(), BZDB.eval(name));
739         ((BZAdminClient*)thisObject)->ui->outputMessage(message, Default);
740     }
741 }
742 
743 
getMessageTypeMap() const744 const std::map<std::string, uint16_t>& BZAdminClient::getMessageTypeMap() const
745 {
746     return msgTypeMap;
747 }
748 
getFilterStatus(uint16_t msgType) const749 bool BZAdminClient::getFilterStatus(uint16_t msgType) const
750 {
751     std::map<uint16_t, bool>::const_iterator iter = messageMask.find(msgType);
752     if (iter == messageMask.end())
753         return false;
754     else
755         return iter->second;
756 }
757 
758 
759 // Local Variables: ***
760 // mode: C++ ***
761 // tab-width: 4 ***
762 // c-basic-offset: 4 ***
763 // indent-tabs-mode: nil ***
764 // End: ***
765 // ex: shiftwidth=4 tabstop=4
766