BruteDialog.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*
  2. * This file is part of XDRE.
  3. *
  4. * XDRE is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * XDRE is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with XDRE. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Этот файл — часть XDRE.
  18. *
  19. * XDRE — свободная программа: вы можете перераспространять её и/или
  20. * изменять её на условиях Стандартной общественной лицензии GNU в том виде,
  21. * в каком она была опубликована Фондом свободного программного обеспечения;
  22. * либо версии 2 лицензии, либо (по вашему выбору) любой более поздней
  23. * версии.
  24. *
  25. * XDRE распространяется в надежде, что она будет полезной,
  26. * но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
  27. * или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
  28. * общественной лицензии GNU.
  29. *
  30. * Вы должны были получить копию Стандартной общественной лицензии GNU
  31. * вместе с этой программой. Если это не так, см.
  32. * <http://www.gnu.org/licenses/>.
  33. *
  34. * Description: brute force dialog.
  35. */
  36. #include "BruteDialog.hpp"
  37. #include <wx/intl.h>
  38. #include <wx/string.h>
  39. #include <wx/valnum.h>
  40. #include <wx/valtext.h>
  41. #include <wx/msgdlg.h>
  42. #include <wx/tokenzr.h>
  43. class BruteException : public std::exception {
  44. public:
  45. BruteException(const char* str) : str{str} {}
  46. virtual const char* what() const noexcept {return str;}
  47. const char* str;
  48. };
  49. const long BruteDialog::ID_BRUTETICSBOX = wxNewId();
  50. const long BruteDialog::ID_BRUTETICINPUT = wxNewId();
  51. const long BruteDialog::ID_STRAFECMDINPUT = wxNewId();
  52. const long BruteDialog::ID_RUNCMDINPUT = wxNewId();
  53. const long BruteDialog::ID_TURNCMDINPUT = wxNewId();
  54. const long BruteDialog::ID_TURNANGLEBUTTON = wxNewId();
  55. const long BruteDialog::ID_FIRERADIOBOX = wxNewId();
  56. const long BruteDialog::ID_USERADIOBOX = wxNewId();
  57. const long BruteDialog::ID_CANCEL = wxNewId();
  58. const long BruteDialog::ID_START = wxNewId();
  59. const long BruteDialog::ID_ADDBUTTON = wxNewId();
  60. const long BruteDialog::ID_REMOVEBUTTON = wxNewId();
  61. wxDEFINE_EVENT(EVT_BRUTE_DONE, wxThreadEvent);
  62. BEGIN_EVENT_TABLE(BruteDialog,wxDialog)
  63. END_EVENT_TABLE()
  64. BruteDialog::BruteDialog(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) {
  65. wxDialog::Create(parent, wxID_ANY, _("Brute force"));
  66. SetClientSize(wxSize(400,440));
  67. SetMinSize(wxSize(400,440));
  68. SetMaxSize(wxSize(400,-1));
  69. p = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(400,440), wxTAB_TRAVERSAL);
  70. checkTicInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(288,44), wxSize(96,21), wxTE_RIGHT, wxIntegerValidator<unsigned int>());
  71. rngInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,80), wxSize(56,21), wxTE_RIGHT);
  72. damageInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,112), wxSize(56,21), wxTE_RIGHT, wxIntegerValidator<unsigned int>());
  73. xPosInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,144), wxSize(56,21), wxTE_RIGHT, wxFloatingPointValidator<double>());
  74. yPosInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,176), wxSize(56,21), wxTE_RIGHT, wxFloatingPointValidator<double>());
  75. zPosInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,208), wxSize(56,21), wxTE_RIGHT, wxIntegerValidator<int>());
  76. xMomInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,240), wxSize(56,21), wxTE_RIGHT, wxFloatingPointValidator<double>());
  77. yMomInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,272), wxSize(56,21), wxTE_RIGHT, wxFloatingPointValidator<double>());
  78. speedInput = new wxTextCtrl(p, wxID_ANY, wxEmptyString, wxPoint(328,304), wxSize(56,21), wxTE_RIGHT, wxFloatingPointValidator<double>());
  79. rngCheckBox = new wxCheckBox(p, wxID_ANY, _("RNG index"), wxPoint(204,84), wxDefaultSize, wxALIGN_RIGHT);
  80. rngCheckBox->SetValue(false);
  81. rngChoice = new wxChoice(p, wxID_ANY, wxPoint(280,80), wxSize(40,21), 0, 0, 0, wxDefaultValidator);
  82. rngChoice->SetSelection( rngChoice->Append(_("=")) );
  83. rngChoice->Append(_("!="));
  84. damageCheckBox = new wxCheckBox(p, wxID_ANY, _("Damage"), wxPoint(216,116), wxDefaultSize, wxALIGN_RIGHT);
  85. damageCheckBox->SetValue(false);
  86. damageChoice = new wxChoice(p, wxID_ANY, wxPoint(280,112), wxSize(40,21), 0, 0, 0);
  87. damageChoice->SetSelection( damageChoice->Append(_("=")) );
  88. damageChoice->Append(_(">="));
  89. damageChoice->Append(_(">"));
  90. damageChoice->Append(_("<="));
  91. damageChoice->Append(_("<"));
  92. xPosCheckBox = new wxCheckBox(p, wxID_ANY, _("X"), wxPoint(248,148), wxDefaultSize, wxALIGN_RIGHT);
  93. xPosCheckBox->SetValue(false);
  94. xPosChoice = new wxChoice(p, wxID_ANY, wxPoint(280,144), wxSize(40,21), 0, 0, 0);
  95. xPosChoice->SetSelection(xPosChoice->Append(_("=")));
  96. xPosChoice->Append(_(">="));
  97. xPosChoice->Append(_(">"));
  98. xPosChoice->Append(_("<="));
  99. xPosChoice->Append(_("<"));
  100. yPosCheckBox = new wxCheckBox(p, wxID_ANY, _("Y"), wxPoint(248,180), wxDefaultSize, wxALIGN_RIGHT);
  101. yPosCheckBox->SetValue(false);
  102. yPosChoice = new wxChoice(p, wxID_ANY, wxPoint(280,176), wxSize(40,21), 0, 0, 0);
  103. yPosChoice->SetSelection(yPosChoice->Append(_("=")));
  104. yPosChoice->Append(_(">="));
  105. yPosChoice->Append(_(">"));
  106. yPosChoice->Append(_("<="));
  107. yPosChoice->Append(_("<"));
  108. zPosCheckBox = new wxCheckBox(p, wxID_ANY, _("Z"), wxPoint(248,212), wxDefaultSize, wxALIGN_RIGHT);
  109. zPosCheckBox->SetValue(false);
  110. zPosChoice = new wxChoice(p, wxID_ANY, wxPoint(280,208), wxSize(40,21), 0, 0, 0);
  111. zPosChoice->SetSelection(zPosChoice->Append(_("=")));
  112. zPosChoice->Append(_(">="));
  113. zPosChoice->Append(_(">"));
  114. zPosChoice->Append(_("<="));
  115. zPosChoice->Append(_("<"));
  116. xMomCheckBox = new wxCheckBox(p, wxID_ANY, _("X mom."), wxPoint(220,244), wxDefaultSize, wxALIGN_RIGHT);
  117. xMomCheckBox->SetValue(false);
  118. xMomChoice = new wxChoice(p, wxID_ANY, wxPoint(280,240), wxSize(40,21), 0, 0, 0);
  119. xMomChoice->SetSelection(xMomChoice->Append(_("=")));
  120. xMomChoice->Append(_(">="));
  121. xMomChoice->Append(_(">"));
  122. xMomChoice->Append(_("<="));
  123. xMomChoice->Append(_("<"));
  124. yMomCheckBox = new wxCheckBox(p, wxID_ANY, _("Y mom."), wxPoint(220,276), wxDefaultSize, wxALIGN_RIGHT);
  125. yMomCheckBox->SetValue(false);
  126. yMomChoice = new wxChoice(p, wxID_ANY, wxPoint(280,272), wxSize(40,21), 0, 0, 0);
  127. yMomChoice->SetSelection(yMomChoice->Append(_("=")));
  128. yMomChoice->Append(_(">="));
  129. yMomChoice->Append(_(">"));
  130. yMomChoice->Append(_("<="));
  131. yMomChoice->Append(_("<"));
  132. speedCheckBox = new wxCheckBox(p, wxID_ANY, _("Speed"), wxPoint(224,308), wxDefaultSize, wxALIGN_RIGHT);
  133. speedCheckBox->SetValue(false);
  134. speedChoice = new wxChoice(p, wxID_ANY, wxPoint(280,304), wxSize(40,21), 0, 0, 0);
  135. speedChoice->SetSelection(speedChoice->Append(_("=")));
  136. speedChoice->Append(_(">="));
  137. speedChoice->Append(_(">"));
  138. speedChoice->Append(_("<="));
  139. speedChoice->Append(_("<"));
  140. useCheckBox = new wxCheckBox(p, wxID_ANY, _("Use"), wxPoint(240,340), wxDefaultSize, wxALIGN_RIGHT);
  141. useCheckBox->SetValue(false);
  142. bruteTicsBox = new wxListBox(p, ID_BRUTETICSBOX, wxPoint(16,40), wxSize(168,80), 0, 0, 0);
  143. addButton = new wxButton(p, ID_ADDBUTTON, _("Add"), wxPoint(16,128), wxSize(74,-1), 0);
  144. removeButton = new wxButton(p, ID_REMOVEBUTTON, _("Remove"), wxPoint(110,128), wxSize(74,-1), 0);
  145. removeButton->Disable();
  146. bruteTicInput = new wxTextCtrl(p, ID_BRUTETICINPUT, wxEmptyString, wxPoint(88,160), wxSize(96,21), wxTE_RIGHT, wxIntegerValidator<unsigned int>());
  147. bruteTicInput->Disable();
  148. strafeCmdInput = new wxTextCtrl(p, ID_STRAFECMDINPUT, wxEmptyString, wxPoint(88,184), wxSize(96,21), wxTE_RIGHT, wxTextValidator());
  149. strafeCmdInput->Disable();
  150. runCmdInput = new wxTextCtrl(p, ID_RUNCMDINPUT, wxEmptyString, wxPoint(88,208), wxSize(96,21), wxTE_RIGHT, wxTextValidator());
  151. runCmdInput->Disable();
  152. turnCmdInput = new wxTextCtrl(p, ID_TURNCMDINPUT, wxEmptyString, wxPoint(88,232), wxSize(96,21), wxTE_RIGHT, wxTextValidator());
  153. turnCmdInput->Disable();
  154. turnAngleButton = new wxButton(p, ID_TURNANGLEBUTTON, _("Turn cmds"), wxPoint(16,232), wxSize(67,23), 0);
  155. turnAngleButton->Disable();
  156. wxString __wxRadioBoxChoices_1[3] = {_("No"), _("Both"), _("Yes")};
  157. fireRadioBox = new wxRadioBox(p, ID_FIRERADIOBOX, _("Fire"), wxPoint(72,256), wxSize(56,88), 3, __wxRadioBoxChoices_1, 3, wxRA_VERTICAL);
  158. fireRadioBox->SetSelection(0);
  159. fireRadioBox->Disable();
  160. wxString __wxRadioBoxChoices_2[3] = {_("No"), _("Both"), _("Yes")};
  161. useRadioBox = new wxRadioBox(p, ID_USERADIOBOX, _("Use"), wxPoint(128,256), wxSize(56,88), 3, __wxRadioBoxChoices_2, 3, wxRA_VERTICAL);
  162. useRadioBox->SetSelection(0);
  163. useRadioBox->Disable();
  164. cancel = new wxButton(p, ID_CANCEL, _("Cancel"), wxPoint(248,392), wxDefaultSize, 0, wxDefaultValidator);
  165. start = new wxButton(p, ID_START, _("Start"), wxPoint(80,392), wxDefaultSize, 0, wxDefaultValidator);
  166. workingText = new wxStaticText(p, wxID_ANY, _("Working..."), wxPoint(176,396), wxDefaultSize, 0);
  167. workingText->Hide();
  168. StaticBox1 = new wxStaticBox(p, wxID_ANY, _("Checks"), wxPoint(200,8), wxSize(192,376), 0);
  169. StaticBox2 = new wxStaticBox(p, wxID_ANY, _("Tics to brute force"), wxPoint(8,8), wxSize(192,336), 0);
  170. StaticText1 = new wxStaticText(p, wxID_ANY, _("On tic"), wxPoint(248,48), wxDefaultSize, 0);
  171. StaticText2 = new wxStaticText(p, wxID_ANY, _("Tic"), wxPoint(62,164), wxDefaultSize, 0);
  172. StaticText3 = new wxStaticText(p, wxID_ANY, _("Run cmds"), wxPoint(26,212), wxDefaultSize, 0);
  173. StaticText4 = new wxStaticText(p, wxID_ANY, _("Strafe cmds"), wxPoint(16,188), wxDefaultSize, 0);
  174. Connect(ID_BRUTETICSBOX, wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler(BruteDialog::OnBruteTicsBoxSelect));
  175. Connect(ID_BRUTETICINPUT, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(BruteDialog::OnBruteTicInputText));
  176. Connect(ID_STRAFECMDINPUT, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(BruteDialog::OnStrafeCmdInputText));
  177. Connect(ID_RUNCMDINPUT, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(BruteDialog::OnRunCmdInputText));
  178. Connect(ID_TURNCMDINPUT, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(BruteDialog::OnTurnCmdInputText));
  179. Connect(ID_FIRERADIOBOX, wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(BruteDialog::OnFireRadioBoxSelect));
  180. Connect(ID_USERADIOBOX, wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(BruteDialog::OnUseRadioBoxSelect));
  181. Connect(ID_TURNANGLEBUTTON, wxEVT_BUTTON, wxCommandEventHandler(BruteDialog::OnTurnAngleButtonClick));
  182. Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(BruteDialog::OnClose));
  183. Connect(ID_CANCEL, wxEVT_BUTTON, wxCommandEventHandler(BruteDialog::OnCancelClick));
  184. Connect(ID_START, wxEVT_BUTTON, wxCommandEventHandler(BruteDialog::OnStartClick));
  185. Connect(ID_ADDBUTTON, wxEVT_BUTTON, wxCommandEventHandler(BruteDialog::OnAddButtonClick));
  186. Connect(ID_REMOVEBUTTON, wxEVT_BUTTON, wxCommandEventHandler(BruteDialog::OnRemoveButtonClick));
  187. (*checkTicInput) << static_cast<long>(xdre::getCurrentTic());
  188. rngInput->ChangeValue("0");
  189. damageInput->ChangeValue("0");
  190. xPosInput->ChangeValue("0");
  191. yPosInput->ChangeValue("0");
  192. zPosInput->ChangeValue("0");
  193. xMomInput->ChangeValue("0");
  194. yMomInput->ChangeValue("0");
  195. speedInput->ChangeValue("0");
  196. }
  197. BruteDialog::~BruteDialog() {}
  198. std::vector<signed char> BruteDialog::ParseCmds(wxString str, bool parseAsUnsigned) {
  199. long limitMax = 127;
  200. long limitMin = -128;
  201. if(parseAsUnsigned) {
  202. limitMax = 255;
  203. limitMin = 0;
  204. }
  205. std::vector<signed char> ret;
  206. auto cmds = wxStringTokenize(str, ",", wxTOKEN_STRTOK);
  207. for(auto& cmd : cmds) {
  208. auto range = wxStringTokenize(cmd, ":", wxTOKEN_STRTOK);
  209. if(range.GetCount() == 1) {
  210. long num;
  211. if(cmd.ToLong(&num)) {
  212. if(num > limitMax || num < limitMin) throw BruteException("Too big input value given.");
  213. ret.push_back(num);
  214. } else {
  215. throw BruteException("Invalid value.");
  216. }
  217. } else if(range.GetCount() == 2) {
  218. long start;
  219. long end;
  220. if(!range[0].ToLong(&start) || !range[1].ToLong(&end)) throw BruteException("Invalid range given.");
  221. if(start > limitMax || start < limitMin || end > limitMax || end < limitMin)
  222. throw BruteException("Too big input value given.");
  223. if(start <= end) for(; start <= end; ++start) ret.push_back(start);
  224. else for(; start >= end; --start) ret.push_back(start);
  225. } else throw BruteException("Invalid range given.");
  226. }
  227. return ret;
  228. }
  229. std::vector<BruteTic> BruteDialog::CreateBruteTics() {
  230. std::vector<BruteTic> ret;
  231. for(auto& item : items) {
  232. BruteTic tic;
  233. long num;
  234. if(!item.ticStr.ToLong(&num)) {
  235. throw BruteException("Tic value not a number.");
  236. } else if(num < 0) {throw BruteException("Tic value < 0.");}
  237. tic.tic = num;
  238. tic.fire = item.fire - 1;
  239. tic.use = item.use - 1;
  240. if(tic.fire < -1 || tic.fire > 1 || tic.use < -1 || tic.use > 1) throw BruteException("Invalid fire/use choices.");
  241. bool turnsUnsigned;
  242. if(item.turnOrAngle == 0) {
  243. tic.turnsAreAngles = false;
  244. turnsUnsigned = false;
  245. } else {
  246. tic.turnsAreAngles = true;
  247. turnsUnsigned = true;
  248. }
  249. tic.runCmds = ParseCmds(item.runStr);
  250. tic.strafeCmds = ParseCmds(item.strafeStr);
  251. tic.turnCmds = ParseCmds(item.turnStr, turnsUnsigned);
  252. if(tic.runCmds.empty() || tic.strafeCmds.empty() || tic.turnCmds.empty()) throw BruteException("Empty field.");
  253. ret.push_back(tic);
  254. }
  255. return ret;
  256. }
  257. BruteCheck BruteDialog::CreateBruteCheck() {
  258. BruteCheck check;
  259. long tic;
  260. if(!checkTicInput->GetValue().ToLong(&tic)) {
  261. throw BruteException("Checktic not a number.");
  262. } else if(tic < 0) {throw BruteException("Checktic < 0.");}
  263. check.tic = tic;
  264. //TODO: refactor this shit
  265. if(rngCheckBox->GetValue()) {
  266. auto indexes = ParseCmds(rngInput->GetValue(), true);
  267. switch(rngChoice->GetSelection()) {
  268. case 0:
  269. check.rngFunc = [indexes](int val) {
  270. for(auto index : indexes) {
  271. if(val == index) return true;
  272. }
  273. return false;
  274. };
  275. break;
  276. case 1:
  277. check.rngFunc = [indexes](int val) {
  278. for(auto index : indexes) {
  279. if(val == index) return false;
  280. }
  281. return true;
  282. };
  283. break;
  284. }
  285. } else {check.rngFunc = [](int val){return true;};}
  286. if(damageCheckBox->GetValue()) {
  287. long num;
  288. if(!damageInput->GetValue().ToLong(&num)) throw BruteException("Invalid damage.");
  289. switch(damageChoice->GetSelection()) {
  290. case 0: check.damageFunc = [num](int val){return val == num;}; break;
  291. case 1: check.damageFunc = [num](int val){return val >= num;}; break;
  292. case 2: check.damageFunc = [num](int val){return val > num;}; break;
  293. case 3: check.damageFunc = [num](int val){return val <= num;}; break;
  294. case 4: check.damageFunc = [num](int val){return val < num;}; break;
  295. }
  296. } else {check.damageFunc = [](int val){return true;};}
  297. if(xPosCheckBox->GetValue()) {
  298. double dbl;
  299. if(!xPosInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid X position.");
  300. switch(xPosChoice->GetSelection()) {
  301. case 0: check.xPosFunc = [dbl](double val){return val == dbl;}; break;
  302. case 1: check.xPosFunc = [dbl](double val){return val >= dbl;}; break;
  303. case 2: check.xPosFunc = [dbl](double val){return val > dbl;}; break;
  304. case 3: check.xPosFunc = [dbl](double val){return val <= dbl;}; break;
  305. case 4: check.xPosFunc = [dbl](double val){return val < dbl;}; break;
  306. }
  307. } else {check.xPosFunc = [](double val){return true;};}
  308. if(yPosCheckBox->GetValue()) {
  309. double dbl;
  310. if(!yPosInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid Y position.");
  311. switch(yPosChoice->GetSelection()) {
  312. case 0: check.yPosFunc = [dbl](double val){return val == dbl;}; break;
  313. case 1: check.yPosFunc = [dbl](double val){return val >= dbl;}; break;
  314. case 2: check.yPosFunc = [dbl](double val){return val > dbl;}; break;
  315. case 3: check.yPosFunc = [dbl](double val){return val <= dbl;}; break;
  316. case 4: check.yPosFunc = [dbl](double val){return val < dbl;}; break;
  317. }
  318. } else {check.yPosFunc = [](double val){return true;};}
  319. if(zPosCheckBox->GetValue()) {
  320. double dbl;
  321. if(!zPosInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid Z position.");
  322. switch(zPosChoice->GetSelection()) {
  323. case 0: check.zPosFunc = [dbl](double val){return val == dbl;}; break;
  324. case 1: check.zPosFunc = [dbl](double val){return val >= dbl;}; break;
  325. case 2: check.zPosFunc = [dbl](double val){return val > dbl;}; break;
  326. case 3: check.zPosFunc = [dbl](double val){return val <= dbl;}; break;
  327. case 4: check.zPosFunc = [dbl](double val){return val < dbl;}; break;
  328. }
  329. } else {check.zPosFunc = [](double val){return true;};}
  330. if(xMomCheckBox->GetValue()) {
  331. double dbl;
  332. if(!xMomInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid X momentum.");
  333. switch(xMomChoice->GetSelection()) {
  334. case 0: check.xMomFunc = [dbl](double val){return val == dbl;}; break;
  335. case 1: check.xMomFunc = [dbl](double val){return val >= dbl;}; break;
  336. case 2: check.xMomFunc = [dbl](double val){return val > dbl;}; break;
  337. case 3: check.xMomFunc = [dbl](double val){return val <= dbl;}; break;
  338. case 4: check.xMomFunc = [dbl](double val){return val < dbl;}; break;
  339. }
  340. } else {check.xMomFunc = [](double val){return true;};}
  341. if(yMomCheckBox->GetValue()) {
  342. double dbl;
  343. if(!yMomInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid Y momentum.");
  344. switch(yMomChoice->GetSelection()) {
  345. case 0: check.yMomFunc = [dbl](double val){return val == dbl;}; break;
  346. case 1: check.yMomFunc = [dbl](double val){return val >= dbl;}; break;
  347. case 2: check.yMomFunc = [dbl](double val){return val > dbl;}; break;
  348. case 3: check.yMomFunc = [dbl](double val){return val <= dbl;}; break;
  349. case 4: check.yMomFunc = [dbl](double val){return val < dbl;}; break;
  350. }
  351. } else {check.yMomFunc = [](double val){return true;};}
  352. if(speedCheckBox->GetValue()) {
  353. double dbl;
  354. if(!speedInput->GetValue().ToDouble(&dbl)) throw BruteException("Invalid speed.");
  355. switch(speedChoice->GetSelection()) {
  356. case 0: check.speedFunc = [dbl](double val){return val == dbl;}; break;
  357. case 1: check.speedFunc = [dbl](double val){return val >= dbl;}; break;
  358. case 2: check.speedFunc = [dbl](double val){return val > dbl;}; break;
  359. case 3: check.speedFunc = [dbl](double val){return val <= dbl;}; break;
  360. case 4: check.speedFunc = [dbl](double val){return val < dbl;}; break;
  361. }
  362. } else {check.speedFunc = [](double val){return true;};}
  363. check.use = useCheckBox->GetValue();
  364. return check;
  365. }
  366. void BruteDialog::ShowData(int n) {
  367. ListItem const& data = items.at(n);
  368. bruteTicInput->ChangeValue(data.ticStr);
  369. runCmdInput->ChangeValue(data.runStr);
  370. strafeCmdInput->ChangeValue(data.strafeStr);
  371. turnCmdInput->ChangeValue(data.turnStr);
  372. fireRadioBox->SetSelection(data.fire);
  373. useRadioBox->SetSelection(data.use);
  374. turnAngleButton->SetLabel(turnAngleTexts[data.turnOrAngle]);
  375. }
  376. void BruteDialog::EnableStuff() {
  377. bruteTicInput->Enable();
  378. runCmdInput->Enable();
  379. strafeCmdInput->Enable();
  380. turnCmdInput->Enable();
  381. fireRadioBox->Enable();
  382. useRadioBox->Enable();
  383. turnAngleButton->Enable();
  384. removeButton->Enable();
  385. }
  386. void BruteDialog::DisableStuff() {
  387. bruteTicInput->Disable();
  388. runCmdInput->Disable();
  389. strafeCmdInput->Disable();
  390. turnCmdInput->Disable();
  391. fireRadioBox->Disable();
  392. useRadioBox->Disable();
  393. turnAngleButton->Disable();
  394. removeButton->Disable();
  395. }
  396. void BruteDialog::OnClose(wxCloseEvent& event) {
  397. if(GetThread() && GetThread()->IsRunning()) return;
  398. Destroy();
  399. }
  400. void BruteDialog::OnCancelClick(wxCommandEvent& event)
  401. {
  402. if(GetThread() && GetThread()->IsRunning()) {
  403. abortBrute = true;
  404. GetThread()->Wait();
  405. return;
  406. }
  407. Close();
  408. }
  409. void BruteDialog::OnTurnAngleButtonClick(wxCommandEvent& event) {
  410. auto item = bruteTicsBox->GetSelection();
  411. if(items[item].turnOrAngle) {
  412. items[item].turnOrAngle = 0;
  413. } else {items[item].turnOrAngle = 1;}
  414. turnAngleButton->SetLabel(turnAngleTexts[items[item].turnOrAngle]);
  415. }
  416. void BruteDialog::OnAddButtonClick(wxCommandEvent& event) {
  417. items.push_back({});
  418. int last = items.size() - 1;
  419. bruteTicsBox->Append(items.at(last).ticStr);
  420. bruteTicsBox->SetSelection(last);
  421. items.at(last).ticStr = wxString::Format(wxT("%i"), xdre::getCurrentTic());
  422. bruteTicsBox->SetString(last, items.at(last).ticStr);
  423. EnableStuff();
  424. ShowData(last);
  425. }
  426. void BruteDialog::OnRemoveButtonClick(wxCommandEvent& event) {
  427. int item = bruteTicsBox->GetSelection();
  428. if(item == wxNOT_FOUND) return;
  429. bruteTicsBox->Delete(item);
  430. items.erase(std::begin(items) + item);
  431. int sel = item < items.size() ? item : items.size() - 1;
  432. bruteTicsBox->SetSelection(sel);
  433. if(sel >= 0) ShowData(sel);
  434. if(bruteTicsBox->GetCount() < 1) DisableStuff();
  435. }
  436. void BruteDialog::OnBruteTicsBoxSelect(wxCommandEvent& event) {ShowData(bruteTicsBox->GetSelection());}
  437. void BruteDialog::OnBruteTicInputText(wxCommandEvent& event) {
  438. int item = bruteTicsBox->GetSelection();
  439. if(item == wxNOT_FOUND) return;
  440. items.at(item).ticStr = bruteTicInput->GetValue();
  441. if(items.at(item).ticStr.IsSameAs("")) items.at(item).ticStr = "_";
  442. bruteTicsBox->SetString(item, items.at(item).ticStr);
  443. }
  444. void BruteDialog::OnRunCmdInputText(wxCommandEvent& event) {
  445. int item = bruteTicsBox->GetSelection();
  446. if(item == wxNOT_FOUND) return;
  447. items.at(item).runStr = runCmdInput->GetValue();
  448. }
  449. void BruteDialog::OnStrafeCmdInputText(wxCommandEvent& event) {
  450. int item = bruteTicsBox->GetSelection();
  451. if(item == wxNOT_FOUND) return;
  452. items.at(item).strafeStr = strafeCmdInput->GetValue();
  453. }
  454. void BruteDialog::OnTurnCmdInputText(wxCommandEvent& event) {
  455. int item = bruteTicsBox->GetSelection();
  456. if(item == wxNOT_FOUND)return;
  457. items.at(item).turnStr = turnCmdInput->GetValue();
  458. }
  459. void BruteDialog::OnFireRadioBoxSelect(wxCommandEvent& event) {
  460. int item = bruteTicsBox->GetSelection();
  461. if(item == wxNOT_FOUND) return;
  462. items.at(item).fire = fireRadioBox->GetSelection();
  463. }
  464. void BruteDialog::OnUseRadioBoxSelect(wxCommandEvent& event) {
  465. int item = bruteTicsBox->GetSelection();
  466. if(item == wxNOT_FOUND) return;
  467. items.at(item).use = useRadioBox->GetSelection();
  468. }
  469. wxThread::ExitCode BruteDialog::Entry() {
  470. bruteSuccess = xdre::bruteForce(bruteTics, bruteCheck, abortBrute);
  471. wxQueueEvent(this, new wxThreadEvent(EVT_BRUTE_DONE));
  472. return static_cast<wxThread::ExitCode>(0);
  473. }
  474. void BruteDialog::OnBruteDone(wxThreadEvent& event) {
  475. Disconnect(wxID_ANY, EVT_BRUTE_DONE, wxThreadEventHandler(BruteDialog::OnBruteDone));
  476. start->Enable();
  477. workingText->Hide();
  478. if(bruteSuccess) {
  479. wxMessageBox("Found it!",
  480. "Success",
  481. wxOK | wxCENTRE,
  482. this);
  483. if(GetThread() && GetThread()->IsRunning()) {
  484. GetThread()->Wait();
  485. }
  486. // Close();
  487. } else if(!bruteSuccess && !abortBrute) {
  488. wxMessageBox("Whole range examined. No cigar.",
  489. "No success",
  490. wxOK | wxCENTRE,
  491. this);
  492. }
  493. }
  494. void BruteDialog::OnStartClick(wxCommandEvent& event)
  495. {
  496. if(GetThread() && GetThread()->IsRunning()) return;
  497. try {
  498. bruteTics = CreateBruteTics();
  499. if(bruteTics.empty()) return;
  500. bruteCheck = CreateBruteCheck();
  501. if(CreateThread(wxTHREAD_JOINABLE) == wxTHREAD_NO_ERROR) {
  502. Connect(wxID_ANY, EVT_BRUTE_DONE, wxThreadEventHandler(BruteDialog::OnBruteDone));
  503. start->Disable();
  504. abortBrute = false;
  505. bruteSuccess = false;
  506. if(GetThread()->Run() == wxTHREAD_NO_ERROR) {
  507. workingText->Show();
  508. } else {
  509. wxMessageBox("Couldn't start brute force thread.",
  510. "Brute force error",
  511. wxOK | wxCENTRE | wxICON_ERROR,
  512. this);
  513. Disconnect(wxID_ANY, EVT_BRUTE_DONE, wxThreadEventHandler(BruteDialog::OnBruteDone));
  514. start->Enable();
  515. workingText->Hide();
  516. }
  517. } else {
  518. wxMessageBox("Couldn't create brute force thread.",
  519. "Brute force error",
  520. wxOK | wxCENTRE | wxICON_ERROR,
  521. this);
  522. }
  523. } catch (BruteException& e) {
  524. wxMessageBox(e.what(),
  525. "Brute force error",
  526. wxOK | wxCENTRE | wxICON_ERROR,
  527. this);
  528. }
  529. }