ManaPlus
chat.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2012-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "actions/chat.h"
23 
24 #include "configuration.h"
25 
26 #include "actions/actiondef.h"
27 
28 #include "being/localplayer.h"
29 
30 #include "gui/sdlinput.h"
31 
32 #include "gui/windows/chatwindow.h"
33 
35 
36 #include "net/charserverhandler.h"
37 #include "net/chathandler.h"
38 #include "net/clanhandler.h"
39 #include "net/guildhandler.h"
40 #include "net/net.h"
41 #include "net/partyhandler.h"
42 
43 #ifdef TMWA_SUPPORT
44 #include "net/tmwa/guildmanager.h"
45 #endif // TMWA_SUPPORT
46 
47 #include "resources/iteminfo.h"
48 
49 #include "resources/db/itemdb.h"
50 
51 #include "utils/booleanoptions.h"
52 #include "utils/chatutils.h"
53 #include "utils/parameters.h"
54 
56 
57 #include "debug.h"
58 
60 
61 namespace Actions
62 {
63 
64 static void outString(ChatTab *const tab,
65  const std::string &str,
66  const std::string &def)
67 {
68  if (tab == nullptr)
69  {
70  if (chatHandler != nullptr)
71  chatHandler->talk(def);
72  return;
73  }
74 
75  switch (tab->getType())
76  {
77  case ChatTabType::CLAN:
78  {
79  if (clanHandler != nullptr)
80  clanHandler->chat(str);
81  break;
82  }
83  case ChatTabType::PARTY:
84  {
85  if (partyHandler != nullptr)
86  partyHandler->chat(str);
87  break;
88  }
89  case ChatTabType::GUILD:
90  {
91  if ((guildHandler == nullptr) || (localPlayer == nullptr))
92  return;
93  const Guild *const guild = localPlayer->getGuild();
94  if (guild != nullptr)
95  {
96 #ifdef TMWA_SUPPORT
97  if (guild->getServerGuild())
98  {
100  return;
101  guildHandler->chat(str);
102  }
103  else if (guildManager != nullptr)
104  {
105  guildManager->chat(str);
106  }
107 #else // TMWA_SUPPORT
108 
109  if (guild->getServerGuild())
110  guildHandler->chat(str);
111 #endif // TMWA_SUPPORT
112  }
113  break;
114  }
116  case ChatTabType::GM:
117  case ChatTabType::TRADE:
118  tab->chatInput(str);
119  break;
120  default:
122  case ChatTabType::INPUT:
124  case ChatTabType::DEBUG:
125  case ChatTabType::BATTLE:
126  case ChatTabType::LANG:
127  if (chatHandler != nullptr)
128  chatHandler->talk(str);
129  break;
130  }
131 }
132 
134 {
135  return chatWindow != nullptr ? chatWindow->requestChatFocus() : false;
136 }
137 
139 {
140  if (chatWindow != nullptr)
141  {
142  chatWindow->prevTab();
143  return true;
144  }
145  return false;
146 }
147 
149 {
150  if (chatWindow != nullptr)
151  {
152  chatWindow->nextTab();
153  return true;
154  }
155  return false;
156 }
157 
159 {
160  if (chatWindow != nullptr)
161  {
162  chatWindow->closeTab();
163  return true;
164  }
165  return false;
166 }
167 
169 {
170  if (chatWindow != nullptr)
171  {
174  return true;
175  }
176  return false;
177 }
178 
180 {
181  if (chatWindow != nullptr)
182  {
185  return true;
186  }
187  return false;
188 }
189 
191 {
192  if ((chatWindow != nullptr) && chatWindow->isWindowVisible())
193  {
195  return true;
196  }
197  return false;
198 }
199 
201 {
202  if ((chatWindow != nullptr) && chatWindow->isWindowVisible())
203  {
205  return true;
206  }
207  return false;
208 }
209 
210 static bool splitWhisper(const std::string &args,
211  std::string &recvnick,
212  std::string &message)
213 {
214  if (args.substr(0, 1) == "\"")
215  {
216  const size_t pos = args.find('"', 1);
217  if (pos != std::string::npos)
218  {
219  recvnick = args.substr(1, pos - 1);
220  if (pos + 2 < args.length())
221  message = args.substr(pos + 2, args.length());
222  }
223  }
224  else
225  {
226  const size_t pos = args.find(' ');
227  if (pos != std::string::npos)
228  {
229  recvnick = args.substr(0, pos);
230  if (pos + 1 < args.length())
231  message = args.substr(pos + 1, args.length());
232  }
233  else
234  {
235  recvnick = std::string(args);
236  message.clear();
237  }
238  }
239 
240  trim(message);
241 
242  if (message.length() > 0)
243  {
244  std::string playerName = localPlayer->getName();
245  std::string tempNick = recvnick;
246 
247  toLower(playerName);
248  toLower(tempNick);
249 
250  if (tempNick == playerName || args.empty())
251  return false;
252 
253  return true;
254  }
255  return false;
256 }
257 
259 {
260  std::string recvnick;
261  std::string message;
262 
263  if (splitWhisper(event.args, recvnick, message))
264  {
265  if (chatWindow == nullptr)
266  return false;
267  ChatTab *const tab = chatWindow->addChatTab(recvnick, false, true);
268  if (tab != nullptr)
269  {
271  tab->chatInput(message);
272  }
273  }
274  else
275  {
276  if (event.tab != nullptr)
277  {
278  event.tab->chatLog(
279  // TRANSLATORS: whisper send
280  _("Cannot send empty whisper or channel message!"),
284  }
285  }
286  return true;
287 }
288 
290 {
291  if (chatWindow == nullptr)
292  return false;
293 
294  if (config.getBoolValue("whispertab"))
295  {
296  chatWindow->localChatInput("/q " + event.args);
297  }
298  else
299  {
301  std::string("/w \"").append(event.args).append("\" "),
302  true);
303  }
304  return true;
305 }
306 
308 {
309  std::string recvnick;
310  std::string message;
311 
312  if (chatHandler != nullptr &&
313  splitWhisper(event.args, recvnick, message))
314  {
315  chatHandler->privateMessage(recvnick, message);
316  }
317  return true;
318 }
319 
321 {
322  const std::string &args = event.args;
323  if (chatWindow != nullptr)
324  {
325  if (chatWindow->addChatTab(args, true, true) != nullptr)
326  {
328  return true;
329  }
330  }
331 
332  if (event.tab != nullptr)
333  {
334  // TRANSLATORS: new whisper or channel query
335  event.tab->chatLog(strprintf(_("Cannot create a whisper tab "
336  "\"%s\"! It probably already exists."),
337  args.c_str()),
341  }
342  return true;
343 }
344 
346 {
347  if (chatWindow != nullptr)
348  {
349  chatWindow->clearTab();
350  return true;
351  }
352  return false;
353 }
354 
356 {
357  if (partyHandler == nullptr)
358  return false;
359 
360  if (event.args.empty())
361  {
362  // TRANSLATORS: dialog header
363  inputActionReplayListener.openDialog(_("Create party"),
364  "",
366  }
367  else
368  {
369  partyHandler->create(event.args);
370  }
371  return true;
372 }
373 
375 {
376  if ((guildHandler == nullptr) ||
378  {
379  return false;
380  }
381 
382  if (event.args.empty())
383  {
384  // TRANSLATORS: dialog header
385  inputActionReplayListener.openDialog(_("Create guild"),
386  "",
388  }
389  else
390  {
391  guildHandler->create(event.args);
392  }
393  return true;
394 }
395 
397 {
398  if (!event.args.empty())
399  {
400  if (partyHandler != nullptr)
401  partyHandler->invite(event.args);
402  }
403  else
404  {
405  if (event.tab != nullptr)
406  {
407  // TRANSLATORS: party invite message
408  event.tab->chatLog(_("Please specify a name."),
412  }
413  }
414  return true;
415 }
416 
418 {
419  if ((guildHandler == nullptr) || (localPlayer == nullptr))
420  return false;
421 
422  const std::string args = event.args;
423  if (!args.empty())
424  {
425  const Guild *const guild = localPlayer->getGuild();
426  if (guild != nullptr)
427  {
428 #ifdef TMWA_SUPPORT
429  if (guild->getServerGuild())
430  guildHandler->invite(args);
431  else if (guildManager != nullptr)
432  GuildManager::invite(args);
433 #else // TMWA_SUPPORT
434 
435  guildHandler->invite(args);
436 #endif // TMWA_SUPPORT
437  }
438  }
439  else
440  {
441  if (event.tab != nullptr)
442  {
443  // TRANSLATORS: guild invite message
444  event.tab->chatLog(_("Please specify a name."),
448  }
449  else if (localChatTab != nullptr)
450  {
451  // TRANSLATORS: guild invite message
452  localChatTab->chatLog(_("Please specify a name."),
456  }
457  }
458  return true;
459 }
460 
461 impHandler(me)
462 {
463  outString(event.tab, textToMe(event.args), event.args);
464  return true;
465 }
466 
468 {
469  if (event.args.empty())
470  {
471  if ((chatWindow != nullptr) && (event.tab != nullptr))
472  {
473  event.tab->chatLog(chatWindow->getReturnTogglesChat() ?
474  // TRANSLATORS: message from toggle chat command
475  _("Return toggles chat.") : _("Message closes chat."),
479  }
480  return true;
481  }
482 
483  switch (parseBoolean(event.args))
484  {
485  case 1:
486  if (event.tab != nullptr)
487  {
488  // TRANSLATORS: message from toggle chat command
489  event.tab->chatLog(_("Return now toggles chat."),
493  }
494  if (chatWindow != nullptr)
496  return true;
497  case 0:
498  if (event.tab != nullptr)
499  {
500  // TRANSLATORS: message from toggle chat command
501  event.tab->chatLog(_("Message now closes chat."),
505  }
506  if (chatWindow != nullptr)
508  return true;
509  case -1:
510  if (event.tab != nullptr)
511  {
512  event.tab->chatLog(strprintf(BOOLEAN_OPTIONS, "toggle"),
516  }
517  return true;
518  default:
519  return true;
520  }
521 }
522 
524 {
525  if (!event.args.empty())
526  {
527  if (partyHandler != nullptr)
528  partyHandler->kick(event.args);
529  }
530  else
531  {
532  if (event.tab != nullptr)
533  {
534  // TRANSLATORS: party kick message
535  event.tab->chatLog(_("Please specify a name."),
539  }
540  }
541  return true;
542 }
543 
545 {
546  if (!event.args.empty())
547  {
548  if (localPlayer != nullptr)
549  {
550  const Guild *const guild = localPlayer->getGuild();
551  if (guild != nullptr)
552  {
553  if (guild->getServerGuild())
554  {
555  if (guildHandler != nullptr)
556  guildHandler->kick(guild->getMember(event.args), "");
557  }
558 #ifdef TMWA_SUPPORT
559  else if (guildManager != nullptr)
560  {
561  GuildManager::kick(event.args);
562  }
563 #endif // TMWA_SUPPORT
564  }
565  }
566  }
567  else
568  {
569  if (event.tab != nullptr)
570  {
571  // TRANSLATORS: party kick message
572  event.tab->chatLog(_("Please specify a name."),
576  }
577  }
578  return true;
579 }
580 
582 {
583  if (chatWindow != nullptr)
584  chatWindow->addInputText(event.args, true);
585  return true;
586 }
587 
589 {
590  if (chatWindow != nullptr)
591  chatWindow->clearTab();
592  return true;
593 }
594 
596 {
597  if (chatWindow != nullptr)
599  return true;
600 }
601 
603 {
604  if (chatWindow != nullptr)
606  return true;
607 }
608 
610 {
611  if (chatWindow != nullptr)
613  return true;
614 }
615 
617 {
618  if (chatWindow != nullptr)
620  return true;
621 }
622 
624 {
625  if (chatWindow != nullptr)
627  return true;
628 }
629 
631 {
632  if (chatWindow != nullptr)
634  return true;
635 }
636 
638 {
639  if (chatWindow != nullptr)
641  return true;
642 }
643 
645 {
646  if (chatWindow != nullptr)
648  return true;
649 }
650 
652 {
653  if ((localPlayer == nullptr) || (charServerHandler == nullptr))
654  return false;
655 
656  const int sprite = localPlayer->getSpriteID(
658  std::string str;
659  if (sprite == 0)
660  {
661  // TRANSLATORS: equipped hat chat message
662  str = _("no hat equipped.");
663  }
664  else
665  {
666  const ItemInfo &info = ItemDB::get(sprite);
667  // TRANSLATORS: equipped hat chat message
668  str = strprintf(_("equipped hat %s."),
669  info.getName().c_str());
670  }
671  outString(event.tab, str, str);
672  return true;
673 }
674 
676 {
677  int x = 0;
678  int y = 0;
679 
680  if ((chatWindow != nullptr) && parse2Int(event.args, x, y))
681  {
683  return true;
684  }
685  return false;
686 }
687 
689 {
690  if (localPlayer == nullptr)
691  return false;
692  const std::string args = event.args;
693  if (args.empty())
694  {
695  // TRANSLATORS: dialog header
696  inputActionReplayListener.openDialog(_("Guild notice"),
697  "",
699  return true;
700  }
701 
702  std::string str2;
703  if (args.size() > 60)
704  str2 = args.substr(60);
705  const Guild *const guild = localPlayer->getGuild();
706  if (guild != nullptr)
707  {
708  guildHandler->changeNotice(guild->getId(),
709  args.substr(0, 60),
710  str2);
711  }
712  return true;
713 }
714 
716 {
717  if (reverseDictionary == nullptr ||
718  localPlayer == nullptr ||
719  event.args.empty())
720  {
721  return false;
722  }
723 
724  ChatTab *const tab = event.tab;
725  if (tab == nullptr)
726  return false;
727 
728  std::string srcStr = event.args;
729  std::string enStr;
730  toLower(srcStr);
731  if (localPlayer->getLanguageId() > 0)
732  {
733  if (reverseDictionary->haveStr(srcStr))
734  enStr = reverseDictionary->getStr(srcStr);
735  else if (dictionary->haveStr(srcStr))
736  enStr = srcStr;
737  }
738  else
739  {
740  if (dictionary->haveStr(srcStr))
741  enStr = srcStr;
742  }
743 
744  if (enStr.empty())
745  {
746  tab->chatLog(
747  // TRANSLATORS: translation error message
748  strprintf(_("No translation found for string: %s"),
749  srcStr.c_str()),
753  return true;
754  }
755 
756  tab->chatInput(enStr);
757  return true;
758 }
759 
761 {
762  if (guiInput == nullptr)
763  return false;
764 
765  const std::string args = event.args;
766  if (args.empty())
767  return false;
768  StringVect pars;
769  if (!splitParameters(pars, args, " ,", '\"'))
770  return false;
771  const int sz = CAST_S32(pars.size());
772  if (sz < 1)
773  return false;
774 
775  int keyValue = atoi(pars[0].c_str());
776  if (keyValue == 0 &&
777  pars[0].size() == 1)
778  {
779  keyValue = CAST_S32(pars[0][0]);
780  }
781  if (sz == 2)
782  {
784  pars[1]);
785  guiInput->simulateKey(keyValue, actionId);
786  }
787  else
788  {
790  }
791  return true;
792 }
793 
795 {
796  if (guiInput == nullptr)
797  return false;
798  const std::string args = event.args;
799  if (args.empty())
800  return false;
801  StringVect pars;
802  if (!splitParameters(pars, args, " ,", '\"'))
803  return false;
804  const int sz = CAST_S32(pars.size());
805  if (sz != 3)
806  return false;
807 
808  const int x = atoi(pars[0].c_str());
809  const int y = atoi(pars[1].c_str());
810  const int key1 = CAST_S32(MouseButton::LEFT);
811  const int key2 = CAST_S32(MouseButton::MIDDLE);
812  const int key = atoi(pars[2].c_str());
813  if (key < key1 || key > key2)
814  return false;
816  y,
817  static_cast<MouseButtonT>(key));
818  return true;
819 }
820 
822 {
823  if (guiInput == nullptr)
824  return false;
825 
826  const std::string args = event.args;
827  if (args.empty())
828  return false;
829 
830  const size_t sz = args.size();
831  for (size_t f = 0; f < sz; f ++)
832  {
833  guiInput->simulateKey(CAST_S32(args[f]),
835  }
836 
837  return true;
838 }
839 
840 } // namespace Actions
#define impHandler0(name)
Definition: actiondef.h:34
#define impHandler(name)
Definition: actiondef.h:33
#define BOOLEAN_OPTIONS
#define CAST_S32
Definition: cast.h:30
Net::CharServerHandler * charServerHandler
Definition: net.cpp:85
Net::ChatHandler * chatHandler
Definition: net.cpp:86
ChatTab * localChatTab
Definition: chattab.cpp:62
std::string textToMe(const std::string &str)
Definition: chatutils.cpp:203
ChatWindow * chatWindow
Definition: chatwindow.cpp:94
Net::ClanHandler * clanHandler
Definition: net.cpp:87
const Guild * getGuild(const std::string &guildName) const
Definition: being.cpp:1258
int getLanguageId()
Definition: being.h:1079
int getSpriteID(const int slot) const
Definition: being.cpp:4894
const std::string & getName() const
Definition: being.h:232
ChatTabTypeT getType() const
Definition: chattab.h:145
void chatLog(std::string line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
Definition: chattab.cpp:111
void chatInput(const std::string &msg)
Definition: chattab.cpp:382
void scroll(const int amount) const
Definition: chatwindow.cpp:733
bool getReturnTogglesChat() const
Definition: chatwindow.h:184
void localChatInput(const std::string &msg) const
Definition: chatwindow.cpp:691
void closeTab() const
Definition: chatwindow.cpp:419
bool requestChatFocus()
Definition: chatwindow.cpp:553
void nextTab()
Definition: chatwindow.cpp:387
void prevTab()
Definition: chatwindow.cpp:373
void copyToClipboard(const int x, const int y) const
void removeAllWhispers()
Definition: chatwindow.cpp:613
static void clearTab(ChatTab *const tab)
Definition: chatwindow.cpp:362
void ignoreAllWhispers()
Definition: chatwindow.cpp:645
void saveState() const
void setReturnTogglesChat(const bool toggles)
Definition: chatwindow.h:187
void addInputText(const std::string &text, const bool space)
ChatTab * addChatTab(const std::string &name, const bool switchTo, const bool join)
void selectTabByType(const ChatTabTypeT &type)
Definition: chatwindow.cpp:401
bool getBoolValue(const std::string &key) const
void chat(const std::string &msg)
static void kick(const std::string &msg)
static void invite(const std::string &msg)
Definition: guild.h:70
void openDialog(const std::string &caption, const std::string &text, const InputActionT action0)
static InputActionT getActionByConfigField(const std::string &field)
virtual unsigned int hatSprite() const =0
virtual void talk(const std::string &text) const =0
virtual void privateMessage(const std::string &recipient, const std::string &text) const =0
virtual void chat(const std::string &text) const =0
virtual void create(const std::string &name) const =0
virtual void chat(const std::string &text) const =0
virtual void invite(const std::string &name) const =0
virtual void changeNotice(const int guildId, const std::string &msg1, const std::string &msg2) const =0
virtual void kick(const GuildMember *const member, const std::string &reason) const =0
virtual void invite(const std::string &name) const =0
virtual void create(const std::string &name) const =0
virtual void chat(const std::string &text) const =0
virtual void kick(const Being *const player) const =0
bool haveStr(const std::string &str) const
Definition: podict.cpp:59
const std::string getStr(const std::string &str)
Definition: podict.cpp:45
void simulateKey(const int guiKey, const InputActionT actionId)
Definition: sdlinput.cpp:403
void simulateMouseClick(const int x, const int y, const MouseButtonT button)
Definition: sdlinput.cpp:360
bool isWindowVisible() const
Definition: window.h:484
Configuration config
#define _(s)
Definition: gettext.h:35
Net::GuildHandler * guildHandler
Definition: net.cpp:92
GuildManager * guildManager
const bool IgnoreRecord_false
Definition: ignorerecord.h:30
InputAction ::T InputActionT
Definition: inputaction.h:717
InputActionReplayListener inputActionReplayListener
LocalPlayer * localPlayer
MouseButton ::T MouseButtonT
Definition: mousebutton.h:78
bool closeAllChatTabs(InputEvent &event)
Definition: chat.cpp:35
bool me(InputEvent &event)
Definition: chat.cpp:48
bool clearChat(InputEvent &event)
Definition: chat.cpp:53
bool chatLangTab(InputEvent &event)
Definition: chat.cpp:58
bool sendMouseKey(InputEvent &event)
Definition: chat.cpp:67
bool sendChars(InputEvent &event)
Definition: chat.cpp:68
bool chatGuildTab(InputEvent &event)
Definition: chat.cpp:61
bool query(InputEvent &event)
Definition: chat.cpp:42
bool closeChatTab(InputEvent &event)
Definition: chat.cpp:34
static void outString(ChatTab *const tab, const std::string &str, const std::string &def)
Definition: chat.cpp:64
bool guild(InputEvent &event)
Definition: chat.cpp:47
bool scrollChatDown(InputEvent &event)
Definition: chat.cpp:38
bool guildNotice(InputEvent &event)
Definition: chat.cpp:64
bool chatTradeTab(InputEvent &event)
Definition: chat.cpp:57
bool msg(InputEvent &event)
Definition: chat.cpp:39
bool kickGuild(InputEvent &event)
Definition: chat.cpp:51
bool ignoreAllWhispers(InputEvent &event)
Definition: chat.cpp:36
bool sendGuiKey(InputEvent &event)
Definition: chat.cpp:66
bool createGuild(InputEvent &event)
Definition: chat.cpp:45
bool scrollChatUp(InputEvent &event)
Definition: chat.cpp:37
bool chatGmTab(InputEvent &event)
Definition: chat.cpp:59
bool chatClipboard(InputEvent &event)
Definition: chat.cpp:63
bool translate(InputEvent &event)
Definition: chat.cpp:65
bool chatDebugTab(InputEvent &event)
Definition: chat.cpp:55
bool party(InputEvent &event)
Definition: chat.cpp:46
bool msg2(InputEvent &event)
Definition: chat.cpp:41
bool kickParty(InputEvent &event)
Definition: chat.cpp:50
bool chatPartyTab(InputEvent &event)
Definition: chat.cpp:60
bool prevChatTab(InputEvent &event)
Definition: chat.cpp:32
bool createParty(InputEvent &event)
Definition: chat.cpp:44
bool toggleChat(InputEvent &event)
Definition: chat.cpp:31
bool nextChatTab(InputEvent &event)
Definition: chat.cpp:33
bool msgText(InputEvent &event)
Definition: chat.cpp:40
bool chatBattleTab(InputEvent &event)
Definition: chat.cpp:56
bool hat(InputEvent &event)
Definition: chat.cpp:62
bool chatGeneralTab(InputEvent &event)
Definition: chat.cpp:54
bool toggle(InputEvent &event)
Definition: chat.cpp:49
static bool splitWhisper(const std::string &args, std::string &recvnick, std::string &message)
Definition: chat.cpp:210
bool clearChatTab(InputEvent &event)
Definition: chat.cpp:43
bool addText(InputEvent &event)
Definition: chat.cpp:52
bool info(InputEvent &event)
Definition: commands.cpp:57
std::string trim(std::string const &str)
std::string toLower(std::string const &s)
int size()
Definition: emotedb.cpp:306
const ItemInfo & get(const int id)
Definition: itemdb.cpp:792
ServerTypeT getNetworkType()
Definition: net.cpp:189
Net::PartyHandler * partyHandler
Definition: net.cpp:94
bool splitParameters(StringVect &tokens, std::string text, const std::string &separator, const char quote)
Definition: parameters.cpp:103
PoDict * dictionary
Definition: podict.cpp:29
PoDict * reverseDictionary
Definition: podict.cpp:30
const int DEFAULT_CHAT_WINDOW_SCROLL
Definition: chat.cpp:59
SDLInput * guiInput
Definition: sdlinput.cpp:101
bool parse2Int(const std::string &args, int &x, int &y)
std::string strprintf(const char *const format,...)
signed char parseBoolean(const std::string &value)
std::vector< std::string > StringVect
Definition: stringvector.h:29
const bool TryRemoveColors_true