Upstream tarball 10019
[amule.git] / src / TextClient.cpp
blobdc13bd470f70ffb2ee56ceb95f56f7bc06f22846
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 Angel Vidal ( kry@amule.org )
5 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #ifdef HAVE_CONFIG_H
28 #include "config.h" // Needed for VERSION
29 #endif
31 #include <common/ClientVersion.h>
33 #include "TextClient.h"
35 #ifndef __WXMSW__
36 #include <unistd.h> // Do_not_auto_remove
37 #endif
40 //-------------------------------------------------------------------
43 //-------------------------------------------------------------------
45 #include <ec/cpp/ECSpecialTags.h>
47 #include <wx/tokenzr.h>
49 #include <common/Format.h> // Needed for CFormat
50 #include "OtherFunctions.h"
51 #include "KnownFile.h" // Needed for Priority Levels
52 #include "DataToText.cpp" // Needed for PriorityToStr
54 #define APP_INIT_SIZE_X 640
55 #define APP_INIT_SIZE_Y 480
57 #define theApp (*((CamulecmdApp*)wxTheApp))
59 //-------------------------------------------------------------------
61 enum {
62 CMD_ID_STATUS,
63 CMD_ID_RESUME,
64 CMD_ID_PAUSE,
65 CMD_ID_PRIORITY_LOW,
66 CMD_ID_PRIORITY_NORMAL,
67 CMD_ID_PRIORITY_HIGH,
68 CMD_ID_PRIORITY_AUTO,
69 CMD_ID_CANCEL,
70 CMD_ID_CONNECT,
71 CMD_ID_CONNECT_ED2K,
72 CMD_ID_CONNECT_KAD,
73 CMD_ID_DISCONNECT,
74 CMD_ID_DISCONNECT_ED2K,
75 CMD_ID_DISCONNECT_KAD,
76 CMD_ID_RELOAD_SHARED,
77 CMD_ID_RELOAD_IPFILTER_LOCAL,
78 CMD_ID_RELOAD_IPFILTER_NET,
79 CMD_ID_SET_IPFILTER_ON,
80 CMD_ID_SET_IPFILTER_OFF,
81 CMD_ID_SET_IPFILTER_CLIENTS_ON,
82 CMD_ID_SET_IPFILTER_CLIENTS_OFF,
83 CMD_ID_SET_IPFILTER_SERVERS_ON,
84 CMD_ID_SET_IPFILTER_SERVERS_OFF,
85 CMD_ID_SET_IPFILTER_LEVEL,
86 CMD_ID_GET_IPFILTER,
87 CMD_ID_GET_IPFILTER_STATE,
88 CMD_ID_GET_IPFILTER_STATE_CLIENTS,
89 CMD_ID_GET_IPFILTER_STATE_SERVERS,
90 CMD_ID_GET_IPFILTER_LEVEL,
91 CMD_ID_SHOW_UL,
92 CMD_ID_SHOW_DL,
93 CMD_ID_SHOW_LOG,
94 CMD_ID_SHOW_SERVERS,
95 CMD_ID_SHOW_SHARED,
96 CMD_ID_RESET_LOG,
97 CMD_ID_SHUTDOWN,
98 CMD_ID_ADDLINK,
99 CMD_ID_SET_BWLIMIT_UP,
100 CMD_ID_SET_BWLIMIT_DOWN,
101 CMD_ID_GET_BWLIMITS,
102 CMD_ID_STATTREE,
103 CMD_ID_SEARCH,
104 CMD_ID_SEARCH_GLOBAL,
105 CMD_ID_SEARCH_LOCAL,
106 CMD_ID_SEARCH_KAD,
107 CMD_ID_SEARCH_RESULTS,
108 CMD_ID_SEARCH_PROGRESS,
109 CMD_ID_DOWNLOAD,
110 // IDs for deprecated commands
111 CMD_ID_SET_IPFILTER
115 // method to create a SearchFile
116 SearchFile::SearchFile(CEC_SearchFile_Tag *tag)
118 nHash = tag->FileHash();
119 sHash = nHash.Encode();
120 sFileName = tag->FileName();
121 lFileSize = tag->SizeFull();
122 lSourceCount = tag->SourceCount();
123 bPresent = tag->AlreadyHave();
126 //-------------------------------------------------------------------
127 IMPLEMENT_APP (CamulecmdApp)
128 //-------------------------------------------------------------------
130 void CamulecmdApp::OnInitCmdLine(wxCmdLineParser& parser)
132 CaMuleExternalConnector::OnInitCmdLine(parser, "amulecmd");
133 parser.AddOption(wxT("c"), wxT("command"),
134 _("Execute <str> and exit."),
135 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
138 bool CamulecmdApp::OnCmdLineParsed(wxCmdLineParser& parser)
140 m_HasCmdOnCmdLine = parser.Found(wxT("command"), &m_CmdString);
141 if (m_CmdString.Lower().StartsWith(wxT("help")))
143 OnInitCommandSet();
144 printf("%s %s\n", m_appname, (const char *)unicode2char(GetMuleVersion()));
145 Parse_Command(m_CmdString);
146 exit(0);
148 m_interactive = !m_HasCmdOnCmdLine;
149 return CaMuleExternalConnector::OnCmdLineParsed(parser);
152 void CamulecmdApp::TextShell(const wxString& prompt)
154 if (m_HasCmdOnCmdLine)
155 Parse_Command(m_CmdString);
156 else
157 CaMuleExternalConnector::TextShell(prompt);
160 int CamulecmdApp::ProcessCommand(int CmdId)
162 wxString args = GetCmdArgs();
163 CECPacket *request = 0;
164 std::list<CECPacket *> request_list;
165 int tmp_int = 0;
166 EC_SEARCH_TYPE search_type = EC_SEARCH_KAD;
168 // Implementation of the deprecated command 'SetIPFilter'.
169 if (CmdId == CMD_ID_SET_IPFILTER) {
170 if ( ! args.IsEmpty() ) {
171 if (args.IsSameAs(wxT("ON"), false)) {
172 CmdId = CMD_ID_SET_IPFILTER_ON;
173 } else if (args.IsSameAs(wxT("OFF"), false)) {
174 CmdId = CMD_ID_SET_IPFILTER_OFF;
175 } else {
176 return CMD_ERR_INVALID_ARG;
178 } else {
179 CmdId = CMD_ID_GET_IPFILTER_STATE;
183 switch (CmdId) {
184 case CMD_ID_STATUS:
185 request_list.push_back(new CECPacket(EC_OP_STAT_REQ, EC_DETAIL_CMD));
186 break;
188 case CMD_ID_SHUTDOWN:
189 request_list.push_back(new CECPacket(EC_OP_SHUTDOWN));
190 break;
192 case CMD_ID_CONNECT:
193 if ( !args.IsEmpty() ) {
194 unsigned int ip[4];
195 unsigned int port;
196 // Not much we can do against this unicode2char.
197 int result = sscanf(unicode2char(args), "%d.%d.%d.%d:%d", &ip[0], &ip[1], &ip[2], &ip[3], &port);
198 if (result != 5) {
199 // Try to resolve DNS -- good for dynamic IP servers
200 wxString serverName(args.BeforeFirst(wxT(':')));
201 long lPort;
202 bool ok = args.AfterFirst(wxT(':')).ToLong(&lPort);
203 port = (unsigned int)lPort;
204 wxIPV4address a;
205 a.Hostname(serverName);
206 a.Service(port);
207 result = sscanf(unicode2char(a.IPAddress()), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
208 if (serverName.IsEmpty() || !ok || (result != 4)) {
209 Show(_("Invalid IP format. Use xxx.xxx.xxx.xxx:xxxx\n"));
210 return 0;
213 EC_IPv4_t addr;
214 addr.m_ip[0] = ip[0];
215 addr.m_ip[1] = ip[1];
216 addr.m_ip[2] = ip[2];
217 addr.m_ip[3] = ip[3];
218 addr.m_port = port;
219 request = new CECPacket(EC_OP_SERVER_CONNECT);
220 request->AddTag(CECTag(EC_TAG_SERVER, addr));
221 request_list.push_back(request);
222 } else {
223 request_list.push_back(new CECPacket(EC_OP_CONNECT));
225 break;
227 case CMD_ID_CONNECT_ED2K:
228 request_list.push_back(new CECPacket(EC_OP_SERVER_CONNECT));
229 break;
231 case CMD_ID_CONNECT_KAD:
232 request_list.push_back(new CECPacket(EC_OP_KAD_START));
233 break;
235 case CMD_ID_DISCONNECT:
236 request_list.push_back(new CECPacket(EC_OP_DISCONNECT));
237 break;
239 case CMD_ID_DISCONNECT_ED2K:
240 request_list.push_back(new CECPacket(EC_OP_SERVER_DISCONNECT));
241 break;
243 case CMD_ID_DISCONNECT_KAD:
244 request_list.push_back(new CECPacket(EC_OP_KAD_STOP));
245 break;
247 case CMD_ID_RELOAD_SHARED:
248 request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD));
249 break;
251 case CMD_ID_RELOAD_IPFILTER_LOCAL:
252 request_list.push_back(new CECPacket(EC_OP_IPFILTER_RELOAD));
253 break;
255 case CMD_ID_RELOAD_IPFILTER_NET:
256 request = new CECPacket(EC_OP_IPFILTER_UPDATE);
257 request->AddTag(EC_TAG_STRING, args);
258 request_list.push_back(request);
259 break;
261 case CMD_ID_SET_IPFILTER_ON:
262 case CMD_ID_SET_IPFILTER_CLIENTS_ON:
263 case CMD_ID_SET_IPFILTER_SERVERS_ON:
264 tmp_int = 1;
265 case CMD_ID_SET_IPFILTER_OFF:
266 case CMD_ID_SET_IPFILTER_CLIENTS_OFF:
267 case CMD_ID_SET_IPFILTER_SERVERS_OFF:
269 if (CmdId == CMD_ID_SET_IPFILTER_CLIENTS_ON || CmdId == CMD_ID_SET_IPFILTER_CLIENTS_OFF) {
270 CmdId = CMD_ID_GET_IPFILTER_STATE_CLIENTS;
271 } else if (CmdId == CMD_ID_SET_IPFILTER_SERVERS_ON || CmdId == CMD_ID_SET_IPFILTER_SERVERS_OFF) {
272 CmdId = CMD_ID_GET_IPFILTER_STATE_SERVERS;
273 } else {
274 CmdId = CMD_ID_GET_IPFILTER_STATE;
277 request = new CECPacket(EC_OP_SET_PREFERENCES);
278 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY);
279 if (CmdId != CMD_ID_GET_IPFILTER_STATE_SERVERS) {
280 prefs.AddTag(CECTag(EC_TAG_IPFILTER_CLIENTS, (uint8)tmp_int));
282 if (CmdId != CMD_ID_GET_IPFILTER_STATE_CLIENTS) {
283 prefs.AddTag(CECTag(EC_TAG_IPFILTER_SERVERS, (uint8)tmp_int));
285 request->AddTag(prefs);
286 request_list.push_back(request);
288 case CMD_ID_GET_IPFILTER:
289 case CMD_ID_GET_IPFILTER_STATE:
290 case CMD_ID_GET_IPFILTER_STATE_CLIENTS:
291 case CMD_ID_GET_IPFILTER_STATE_SERVERS:
292 request = new CECPacket(EC_OP_GET_PREFERENCES);
293 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY));
294 request_list.push_back(request);
295 break;
297 case CMD_ID_SET_IPFILTER_LEVEL:
298 if (!args.IsEmpty()) // This 'if' must stay as long as we support the deprecated 'IPLevel' command.
300 unsigned long int level = 0;
301 if (args.ToULong(&level) == true && level < 256) {
302 request = new CECPacket(EC_OP_SET_PREFERENCES);
303 CECEmptyTag prefs(EC_TAG_PREFS_SECURITY);
304 prefs.AddTag(CECTag(EC_TAG_IPFILTER_LEVEL, (uint8)level));
305 request->AddTag(prefs);
306 request_list.push_back(request);
307 } else {
308 return CMD_ERR_INVALID_ARG;
311 CmdId = CMD_ID_GET_IPFILTER_LEVEL;
312 case CMD_ID_GET_IPFILTER_LEVEL:
313 request = new CECPacket(EC_OP_GET_PREFERENCES);
314 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_SECURITY));
315 request_list.push_back(request);
316 break;
318 case CMD_ID_PAUSE:
319 case CMD_ID_CANCEL:
320 case CMD_ID_RESUME:
322 if ( args.IsEmpty() ) {
323 Show(_("This command requires an argument. Valid arguments: 'all', filename, or a number.\n"));
324 return 0;
325 } else {
326 wxStringTokenizer argsTokenizer(args);
327 wxString token;
328 CMD4Hash hash;
330 // Grab the entire dl queue right away
331 CECPacket request_all(EC_OP_GET_DLOAD_QUEUE, EC_DETAIL_CMD);
332 const CECPacket *reply_all = SendRecvMsg_v2(&request_all);
334 if (reply_all) {
335 switch(CmdId) {
336 case CMD_ID_PAUSE:
337 request = new CECPacket(EC_OP_PARTFILE_PAUSE); break;
338 case CMD_ID_CANCEL:
339 request = new CECPacket(EC_OP_PARTFILE_DELETE); break;
340 case CMD_ID_RESUME:
341 request = new CECPacket(EC_OP_PARTFILE_RESUME); break;
342 default: wxFAIL;
345 // We loop through all the arguments
346 while(argsTokenizer.HasMoreTokens()) {
347 token=argsTokenizer.GetNextToken();
349 // If the user requested all, then we select all files and exit the loop
350 // since there is little point to add anything more to "everything"
351 if( token == wxT("all") ) {
352 for (size_t i = 0; i < reply_all->GetTagCount(); i++) {
353 const CECTag *tag = reply_all->GetTagByIndex(i);
354 if (tag) {
355 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->GetMD4Data()));
357 break;
359 } else if ( hash.Decode(token.Trim(false).Trim(true)) ) {
360 if ( !hash.IsEmpty() ) {
361 Show(_("Processing by hash: "+token+wxT("\n")));
362 request->AddTag(CECTag(EC_TAG_PARTFILE, hash));
364 } else {
365 // Go through the dl queue and look at each filename
366 for (size_t i = 0; i < reply_all->GetTagCount(); i++) {
367 CEC_PartFile_Tag *tag = (CEC_PartFile_Tag *)reply_all->GetTagByIndex(i);
368 if (tag) {
369 wxString partmetname = tag->PartMetName();
371 // We check for filename, XXX.pat.met, XXX.part, XXX
372 if( tag->FileName() == token ||
373 partmetname == token ||
374 partmetname.Truncate(partmetname.Len()-4) == token ||
375 partmetname.Truncate(partmetname.Len()-5) == token) {
376 Show(_("Processing by filename: "+token+wxT("\n")));
377 request->AddTag(CECTag(EC_TAG_PARTFILE, tag->GetMD4Data()));
381 } // End of filename check else
382 } // End of argument token loop
384 request_list.push_back(request);
386 delete reply_all;
388 } // End of dl queue processing
390 } // end of command processing
391 break;
394 case CMD_ID_PRIORITY_LOW:
395 case CMD_ID_PRIORITY_NORMAL:
396 case CMD_ID_PRIORITY_HIGH:
397 case CMD_ID_PRIORITY_AUTO:
398 if ( args.IsEmpty() ) {
399 Show(_("This command requires an argument. Valid arguments: a file hash.\n"));
400 return 0;
401 } else {
402 CMD4Hash hash;
403 if (hash.Decode(args.Trim(false).Trim(true))) {
404 if (!hash.IsEmpty()) {
405 request = new CECPacket(EC_OP_PARTFILE_PRIO_SET);
406 CECTag hashtag(EC_TAG_PARTFILE, hash);
407 switch(CmdId) {
408 case CMD_ID_PRIORITY_LOW:
409 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_LOW));
410 break;
411 case CMD_ID_PRIORITY_NORMAL:
412 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_NORMAL));
413 break;
414 case CMD_ID_PRIORITY_HIGH:
415 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_HIGH));
416 break;
417 case CMD_ID_PRIORITY_AUTO:
418 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, (uint8)PR_AUTO));
419 break;
420 default: wxFAIL;
422 request->AddTag(hashtag);
423 request_list.push_back(request);
424 } else {
425 Show(_("Not a valid number\n"));
426 return 0;
428 } else {
429 Show(_("Not a valid hash (length should be exactly 32 chars)\n"));
430 return 0;
433 break;
435 case CMD_ID_SHOW_UL:
436 request_list.push_back(new CECPacket(EC_OP_GET_ULOAD_QUEUE));
437 break;
439 case CMD_ID_SHOW_DL:
440 request_list.push_back(new CECPacket(EC_OP_GET_DLOAD_QUEUE));
441 break;
443 case CMD_ID_SHOW_LOG:
444 request_list.push_back(new CECPacket(EC_OP_GET_LOG));
445 break;
447 case CMD_ID_SHOW_SERVERS:
448 request_list.push_back(new CECPacket(EC_OP_GET_SERVER_LIST, EC_DETAIL_CMD));
449 break;
451 case CMD_ID_RESET_LOG:
452 request_list.push_back(new CECPacket(EC_OP_RESET_LOG));
453 break;
455 case CMD_ID_ADDLINK:
456 if (args.compare(0, 7, wxT("ed2k://")) == 0) {
457 //aMule doesn't like AICH links without |/| in front of h=
458 if (args.Find(wxT("|h=")) > -1 && args.Find(wxT("|/|h=")) == -1) {
459 args.Replace(wxT("|h="),wxT("|/|h="));
462 request = new CECPacket(EC_OP_ADD_LINK);
463 request->AddTag(CECTag(EC_TAG_STRING, args));
464 request_list.push_back(request);
465 break;
467 case CMD_ID_SET_BWLIMIT_UP:
468 tmp_int = EC_TAG_CONN_MAX_UL - EC_TAG_CONN_MAX_DL;
469 case CMD_ID_SET_BWLIMIT_DOWN:
470 tmp_int += EC_TAG_CONN_MAX_DL;
472 unsigned long int limit;
473 if (args.ToULong(&limit)) {
474 request = new CECPacket(EC_OP_SET_PREFERENCES);
475 CECEmptyTag prefs(EC_TAG_PREFS_CONNECTIONS);
476 prefs.AddTag(CECTag(tmp_int, (uint16)limit));
477 request->AddTag(prefs);
478 request_list.push_back(request);
479 } else {
480 return CMD_ERR_INVALID_ARG;
483 case CMD_ID_GET_BWLIMITS:
484 request = new CECPacket(EC_OP_GET_PREFERENCES);
485 request->AddTag(CECTag(EC_TAG_SELECT_PREFS, (uint32)EC_PREFS_CONNECTIONS));
486 request_list.push_back(request);
487 break;
489 case CMD_ID_STATTREE:
490 request = new CECPacket(EC_OP_GET_STATSTREE);
491 if (!args.IsEmpty()) {
492 unsigned long int max_versions;
493 if (args.ToULong(&max_versions)) {
494 if (max_versions < 256) {
495 request->AddTag(CECTag(EC_TAG_STATTREE_CAPPING, (uint8)max_versions));
496 } else {
497 delete request;
498 return CMD_ERR_INVALID_ARG;
500 } else {
501 delete request;
502 return CMD_ERR_INVALID_ARG;
505 request_list.push_back(request);
506 break;
507 case CMD_ID_SEARCH_GLOBAL:
508 search_type = EC_SEARCH_GLOBAL;
509 case CMD_ID_SEARCH_LOCAL:
510 if (search_type != EC_SEARCH_GLOBAL){
511 search_type = EC_SEARCH_LOCAL;
513 case CMD_ID_SEARCH_KAD:
514 if (search_type != EC_SEARCH_GLOBAL && search_type != EC_SEARCH_LOCAL){
515 search_type = EC_SEARCH_KAD;
517 if (!args.IsEmpty())
519 wxString search = args;
520 wxString type = wxT("");
521 wxString extention = wxT("");
522 uint32 avail = 0;
523 uint32 min_size = 0;
524 uint32 max_size = 0;
526 request = new CECPacket(EC_OP_SEARCH_START);
527 request->AddTag(CEC_Search_Tag (search, search_type, type, extention, avail, min_size, max_size));
528 request_list.push_back(request);
530 break;
531 case CMD_ID_SEARCH:
532 printf("No search type defined.\nType 'help search' to get more help.\n");
533 break;
536 case CMD_ID_SEARCH_RESULTS:
537 request_list.push_back(new CECPacket(EC_OP_SEARCH_RESULTS, EC_DETAIL_FULL));
538 break;
540 case CMD_ID_SEARCH_PROGRESS:
541 request_list.push_back(new CECPacket(EC_OP_SEARCH_PROGRESS));
542 break;
544 case CMD_ID_DOWNLOAD:
545 if (!args.IsEmpty())
547 unsigned long int id = 0;
548 if (args.ToULong(&id) == true && id < m_Results_map.size()) {
550 SearchFile* file = m_Results_map[id];
551 printf("Download File: %lu %s\n", id, (const char*)unicode2char(file->sFileName));
552 request = new CECPacket(EC_OP_DOWNLOAD_SEARCH_RESULT);
553 // get with id the hash and category=0
554 uint32 category = 0;
555 CECTag hashtag(EC_TAG_PARTFILE, file->nHash);
556 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
557 request->AddTag(hashtag);
558 request_list.push_back(request);
559 } else {
560 return CMD_ERR_INVALID_ARG;
563 break;
565 default:
566 return CMD_ERR_PROCESS_CMD;
569 m_last_cmd_id = CmdId;
571 if ( ! request_list.empty() ) {
572 std::list<CECPacket *>::iterator it = request_list.begin();
573 while ( it != request_list.end() ) {
574 CECPacket *curr = *it++;
575 const CECPacket *reply = SendRecvMsg_v2(curr);
576 delete curr;
577 if ( reply ) {
578 Process_Answer_v2(reply);
579 delete reply;
582 request_list.resize(0);
585 if (CmdId == CMD_ID_SHUTDOWN)
586 return CMD_ID_QUIT;
587 else
588 return CMD_OK;
592 * Method to show the results in the console
594 void CamulecmdApp::ShowResults(CResultMap results_map)
596 unsigned int name_max = 80;
597 unsigned int mb_max = 5;
598 unsigned int nr_max = 5;
599 unsigned long int id = 0;
600 wxString output, name, sources, mb , kb;
602 printf("Nr. Filename: Size(MB): Sources: \n");
603 printf("-----------------------------------------------------------------------------------------------------------\n");
605 for( std::map<unsigned long int,SearchFile*>::iterator iter = results_map.begin(); iter != results_map.end(); iter++ ) {
606 id = (*iter).first;
607 SearchFile* file = (*iter).second;
609 output.Printf(wxT("%i. "), id);
610 output = output.SubString(0, nr_max).Append(file->sFileName).Append(' ', name_max);
611 mb.Printf(wxT(" %d"), file->lFileSize/1024/1024);
612 kb.Printf(wxT(".%d"), file->lFileSize/1024%1024);
613 output = output.SubString(0, nr_max + name_max + mb_max - mb.Length() ).Append(mb).Append(kb);
614 printf("%s %ld\n",(const char*)unicode2char(output), file->lSourceCount );
619 // Formats a statistics (sub)tree to text
620 wxString StatTree2Text(CEC_StatTree_Node_Tag *tree, int depth)
622 if (!tree) {
623 return wxEmptyString;
625 wxString result = wxString(wxChar(' '), depth) + tree->GetDisplayString() + wxT("\n");
626 for (size_t i = 0; i < tree->GetTagCount(); ++i) {
627 CEC_StatTree_Node_Tag *tmp = (CEC_StatTree_Node_Tag*)tree->GetTagByIndex(i);
628 if (tmp->GetTagName() == EC_TAG_STATTREE_NODE) {
629 result += StatTree2Text(tmp, depth + 1);
632 return result;
636 * Format EC packet into text form for output to console
638 void CamulecmdApp::Process_Answer_v2(const CECPacket *response)
640 wxString s;
641 wxString msgFailedUnknown(_("Request failed with an unknown error."));
642 wxASSERT(response);
643 switch (response->GetOpCode()) {
644 case EC_OP_NOOP:
645 s << _("Operation was successful.");
646 break;
647 case EC_OP_FAILED:
648 if (response->GetTagCount()) {
649 const CECTag *tag = response->GetTagByIndex(0);
650 if (tag) {
651 s << CFormat(_("Request failed with the following error: %s")) % wxGetTranslation(tag->GetStringData());
652 } else {
653 s << msgFailedUnknown;
655 } else {
656 s << msgFailedUnknown;
658 break;
659 case EC_OP_SET_PREFERENCES:
661 const CECTag *tab = response->GetTagByNameSafe(EC_TAG_PREFS_SECURITY);
662 const CECTag *ipfilterLevel = tab->GetTagByName(EC_TAG_IPFILTER_LEVEL);
663 if (ipfilterLevel) {
664 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
665 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE ||
666 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_CLIENTS) {
667 s << wxString::Format(_("IP filtering for clients is %s.\n"),
668 (tab->GetTagByName(EC_TAG_IPFILTER_CLIENTS) == NULL) ? _("OFF") : _("ON"));
670 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
671 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE ||
672 m_last_cmd_id == CMD_ID_GET_IPFILTER_STATE_SERVERS) {
673 s << wxString::Format(_("IP filtering for servers is %s.\n"),
674 (tab->GetTagByName(EC_TAG_IPFILTER_SERVERS) == NULL) ? _("OFF") : _("ON"));
676 if (m_last_cmd_id == CMD_ID_GET_IPFILTER ||
677 m_last_cmd_id == CMD_ID_GET_IPFILTER_LEVEL) {
678 s << CFormat(_("Current IPFilter Level is %d.\n")) % ipfilterLevel->GetInt();
681 tab = response->GetTagByNameSafe(EC_TAG_PREFS_CONNECTIONS);
682 const CECTag *connMaxUL = tab->GetTagByName(EC_TAG_CONN_MAX_UL);
683 const CECTag *connMaxDL = tab->GetTagByName(EC_TAG_CONN_MAX_DL);
684 if (connMaxUL && connMaxDL) {
685 s << CFormat(_("Bandwidth limits: Up: %u kB/s, Down: %u kB/s.\n"))
686 % connMaxUL->GetInt() % connMaxDL->GetInt();
689 break;
690 case EC_OP_STRINGS:
691 for (size_t i = 0; i < response->GetTagCount(); ++i) {
692 const CECTag *tag = response->GetTagByIndex(i);
693 if (tag) {
694 s << tag->GetStringData() << wxT("\n");
695 } else {
698 break;
699 case EC_OP_STATS: {
700 CEC_ConnState_Tag *connState = (CEC_ConnState_Tag*)response->GetTagByName(EC_TAG_CONNSTATE);
701 if (connState) {
702 s << _("eD2k") << wxT(": ");
703 if (connState->IsConnectedED2K()) {
704 CECTag *server = connState->GetTagByName(EC_TAG_SERVER);
705 CECTag *serverName = server ? server->GetTagByName(EC_TAG_SERVER_NAME) : NULL;
706 if (server && serverName) {
707 s << CFormat(_("Connected to %s %s %s")) %
708 serverName->GetStringData() %
709 server->GetIPv4Data().StringIP() %
710 (connState->HasLowID() ? _("with LowID") : _("with HighID"));
712 } else if (connState->IsConnectingED2K()) {
713 s << _("Now connecting");
714 } else {
715 s << _("Not connected");
717 s << wxT('\n') << _("Kad") << wxT(": ");
718 if (connState->IsKadRunning()) {
719 if (connState->IsConnectedKademlia()) {
720 s << _("Connected") << wxT(" (");
721 if (connState->IsKadFirewalled()) {
722 s << _("firewalled");
723 } else {
724 s << _("ok");
726 s << wxT(')');
727 } else {
728 s << _("Not connected");
730 } else {
731 s << _("Not running");
733 s << wxT('\n');
735 const CECTag *tmpTag;
736 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_DL_SPEED)) != 0) {
737 s << CFormat(_("\nDownload:\t%s")) % CastItoSpeed(tmpTag->GetInt());
739 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_SPEED)) != 0) {
740 s << CFormat(_("\nUpload:\t%s")) % CastItoSpeed(tmpTag->GetInt());
742 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_UL_QUEUE_LEN)) != 0) {
743 s << CFormat(_("\nClients in queue:\t%d\n")) % tmpTag->GetInt();
745 if ((tmpTag = response->GetTagByName(EC_TAG_STATS_TOTAL_SRC_COUNT)) != 0) {
746 s << CFormat(_("\nTotal sources:\t%d\n")) % tmpTag->GetInt();
748 break;
750 case EC_OP_DLOAD_QUEUE:
751 for (size_t i = 0; i < response->GetTagCount(); ++i) {
752 CEC_PartFile_Tag *tag =
753 (CEC_PartFile_Tag *)response->GetTagByIndex(i);
754 if (tag) {
755 uint64 filesize, donesize;
756 filesize = tag->SizeFull();
757 donesize = tag->SizeDone();
758 s << tag->FileHashString() << wxT(" ") <<
759 tag->FileName() <<
760 wxString::Format(wxT("\n\t [%.1f%%] %4i/%4i "),
761 ((float)donesize) / ((float)filesize)*100.0,
762 (int)tag->SourceCount() - (int)tag->SourceNotCurrCount(),
763 (int)tag->SourceCount()) <<
764 ((int)tag->SourceCountA4AF() ? wxString::Format(wxT("+%2.2i "),(int)tag->SourceCountA4AF()) : wxString(wxT(" "))) <<
765 ((int)tag->SourceXferCount() ? wxString::Format(wxT("(%2.2i) - "),(int)tag->SourceXferCount()) : wxString(wxT(" - "))) <<
766 tag->GetFileStatusString();
767 s << wxT(" - ") << tag->PartMetName();
768 if (tag->Prio() < 10) {
769 s << wxT(" - ") << PriorityToStr((int)tag->Prio(), 0);
770 } else {
771 s << wxT(" - ") << PriorityToStr((tag->Prio() - 10), 1);
773 if ( tag->SourceXferCount() > 0) {
774 s << wxT(" - ") + CastItoSpeed(tag->Speed());
776 s << wxT("\n");
779 break;
780 case EC_OP_ULOAD_QUEUE:
781 for (size_t i = 0; i < response->GetTagCount(); ++i) {
782 const CECTag *tag = response->GetTagByIndex(i);
783 const CECTag *clientName = tag ? tag->GetTagByName(EC_TAG_CLIENT_NAME) : NULL;
784 const CECTag *partfileName = tag ? tag->GetTagByName(EC_TAG_PARTFILE_NAME) : NULL;
785 const CECTag *partfileSizeXfer = tag ? tag->GetTagByName(EC_TAG_PARTFILE_SIZE_XFER) : NULL;
786 const CECTag *partfileSpeed = tag ? tag->GetTagByName(EC_TAG_CLIENT_UP_SPEED) : NULL;
787 if (tag && clientName && partfileName && partfileSizeXfer && partfileSpeed) {
788 s << wxT("\n") <<
789 CFormat(wxT("%10u ")) % tag->GetInt() <<
790 clientName->GetStringData() << wxT(" ") <<
791 partfileName->GetStringData() << wxT(" ") <<
792 CastItoXBytes(partfileSizeXfer->GetInt()) << wxT(" ") <<
793 CastItoSpeed(partfileSpeed->GetInt());
796 break;
797 case EC_OP_LOG:
798 for (size_t i = 0; i < response->GetTagCount(); ++i) {
799 const CECTag *tag = response->GetTagByIndex(i);
800 if (tag) {
801 s << tag->GetStringData() << wxT("\n");
802 } else {
805 break;
806 case EC_OP_SERVER_LIST:
807 for (size_t i = 0; i < response->GetTagCount(); i++) {
808 const CECTag *tag = response->GetTagByIndex(i);
809 const CECTag *serverName = tag ? tag->GetTagByName(EC_TAG_SERVER_NAME) : NULL;
810 if (tag && serverName) {
811 wxString ip = tag->GetIPv4Data().StringIP();
812 ip.Append(' ', 24 - ip.Length());
813 s << ip << serverName->GetStringData() << wxT("\n");
816 break;
817 case EC_OP_STATSTREE:
818 s << StatTree2Text((CEC_StatTree_Node_Tag*)response->GetTagByName(EC_TAG_STATTREE_NODE), 0);
819 break;
821 case EC_OP_SEARCH_RESULTS:
822 m_Results_map.clear();
823 s << CFormat(_("Number of search results: %i\n")) % response->GetTagCount();
824 for (size_t i = 0; i < response->GetTagCount(); i++) {
825 CEC_SearchFile_Tag *tag = (CEC_SearchFile_Tag *)response->GetTagByIndex(i);
826 //printf("Tag FileName: %s \n",(const char*)unicode2char(tag->FileName()));
827 //if (tag != NULL)
828 m_Results_map[i] = new SearchFile(tag);
829 //const CECTag *tag = response->GetTagByIndex(i);
832 ShowResults(m_Results_map);
833 break;
835 case EC_OP_SEARCH_PROGRESS:
836 s << _("TODO - show progress of a search");
837 // gives compilation error!!
838 // const CECTag *tab = response->GetTagByNameSafe(EC_TAG_SEARCH_STATUS);
839 //s << wxString::Format(_("Search progress: %u %% \n"),(const char*)unicode2char(tab->GetStringData()));
840 break;
841 default:
842 s << wxString::Format(_("Received an unknown reply from the server, OpCode = %#x."), response->GetOpCode());
844 Process_Answer(s);
847 void CamulecmdApp::OnInitCommandSet()
849 CCommandTree *tmp;
850 CCommandTree *tmp2;
851 CCommandTree *tmp3;
853 CaMuleExternalConnector::OnInitCommandSet();
855 m_commands.AddCommand(wxT("Status"), CMD_ID_STATUS, wxTRANSLATE("Show short status information."),
856 wxTRANSLATE("Show connection status, current up/download speeds, etc.\n"), CMD_PARAM_NEVER);
858 m_commands.AddCommand(wxT("Statistics"), CMD_ID_STATTREE, wxTRANSLATE("Show full statistics tree."),
859 wxTRANSLATE("Optionally, a number in the range 0-255 can be passed as an argument to this\ncommand, which tells how many entries of the client version subtrees should be\nshown. Passing 0 or omitting it means 'unlimited'.\n\nExample: 'statistics 5' will show only the top 5 versions for each client type.\n"));
861 m_commands.AddCommand(wxT("Shutdown"), CMD_ID_SHUTDOWN, wxTRANSLATE("Shut down aMule."),
862 wxTRANSLATE("Shut down the remote running core (amule/amuled).\nThis will also shut down the text client, since it is unusable without a\nrunning core.\n"), CMD_PARAM_NEVER);
864 tmp = m_commands.AddCommand(wxT("Reload"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Reload the given object."), wxEmptyString, CMD_PARAM_NEVER);
865 tmp->AddCommand(wxT("Shared"), CMD_ID_RELOAD_SHARED, wxTRANSLATE("Reload shared files list."), wxEmptyString, CMD_PARAM_NEVER);
867 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload IP filtering table."), wxEmptyString, CMD_PARAM_OPTIONAL);
868 tmp2->AddCommand(wxT("File"), CMD_ID_RELOAD_IPFILTER_LOCAL, wxTRANSLATE("Reload current IP filtering table."), wxEmptyString, CMD_PARAM_NEVER);
869 tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."),
870 wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL);
872 tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."),
873 wxTRANSLATE("This will connect to all networks that are enabled in Preferences.\nYou may also optionally specify a server address in IP:Port form, to connect to\nthat server only. The IP must be a dotted decimal IPv4 address,\nor a resolvable DNS name."), CMD_PARAM_OPTIONAL);
874 tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER);
875 tmp->AddCommand(wxT("Kad"), CMD_ID_CONNECT_KAD, wxTRANSLATE("Connect to Kad only."), wxEmptyString, CMD_PARAM_NEVER);
877 tmp = m_commands.AddCommand(wxT("Disconnect"), CMD_ID_DISCONNECT, wxTRANSLATE("Disconnect from the network."),
878 wxTRANSLATE("This will disconnect from all networks that are currently connected.\n"), CMD_PARAM_NEVER);
879 tmp->AddCommand(wxT("ED2K"), CMD_ID_DISCONNECT_ED2K, wxTRANSLATE("Disconnect from eD2k only."), wxEmptyString, CMD_PARAM_NEVER);
880 tmp->AddCommand(wxT("Kad"), CMD_ID_DISCONNECT_KAD, wxTRANSLATE("Disconnect from Kad only."), wxEmptyString, CMD_PARAM_NEVER);
882 m_commands.AddCommand(wxT("Add"), CMD_ID_ADDLINK, wxTRANSLATE("Add an eD2k or magnet link to core."),
883 wxTRANSLATE("The eD2k link to be added can be:\n*) a file link (ed2k://|file|...), it will be added to the download queue,\n*) a server link (ed2k://|server|...), it will be added to the server list,\n*) or a serverlist link, in which case all servers in the list will be added to the\n server list.\n\nThe magnet link must contain the eD2k hash and file length.\n"), CMD_PARAM_ALWAYS);
885 tmp = m_commands.AddCommand(wxT("Set"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set a preference value."),
886 wxEmptyString, CMD_PARAM_NEVER);
888 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER);
889 tmp2->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_ON, wxTRANSLATE("Turn IP filtering on for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
890 tmp2->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_OFF, wxTRANSLATE("Turn IP filtering off for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
891 tmp3 = tmp2->AddCommand(wxT("Clients"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for clients."), wxEmptyString, CMD_PARAM_NEVER);
892 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_CLIENTS_ON, wxTRANSLATE("Turn IP filtering on for clients."), wxEmptyString, CMD_PARAM_NEVER);
893 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_CLIENTS_OFF, wxTRANSLATE("Turn IP filtering off for clients."), wxEmptyString, CMD_PARAM_NEVER);
894 tmp3 = tmp2->AddCommand(wxT("Servers"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Enable/Disable IP filtering for servers."), wxEmptyString, CMD_PARAM_NEVER);
895 tmp3->AddCommand(wxT("On"), CMD_ID_SET_IPFILTER_SERVERS_ON, wxTRANSLATE("Turn IP filtering on for servers."), wxEmptyString, CMD_PARAM_NEVER);
896 tmp3->AddCommand(wxT("Off"), CMD_ID_SET_IPFILTER_SERVERS_OFF, wxTRANSLATE("Turn IP filtering off for servers."), wxEmptyString, CMD_PARAM_NEVER);
897 tmp2->AddCommand(wxT("Level"), CMD_ID_SET_IPFILTER_LEVEL, wxTRANSLATE("Select IP filtering level."),
898 wxTRANSLATE("Valid filtering levels are in the range 0-255, and it's default (initial)\nvalue is 127.\n"), CMD_PARAM_ALWAYS);
900 tmp2 = tmp->AddCommand(wxT("BwLimit"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set bandwidth limits."),
901 wxTRANSLATE("The value given to these commands has to be in kilobytes/sec.\n"), CMD_PARAM_NEVER);
902 tmp2->AddCommand(wxT("Up"), CMD_ID_SET_BWLIMIT_UP, wxTRANSLATE("Set upload bandwidth limit."),
903 wxT("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS);
904 tmp2->AddCommand(wxT("Down"), CMD_ID_SET_BWLIMIT_DOWN, wxTRANSLATE("Set download bandwidth limit."),
905 wxT("The given value must be in kilobytes/sec.\n"), CMD_PARAM_ALWAYS);
907 tmp = m_commands.AddCommand(wxT("Get"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Get and display a preference value."),
908 wxEmptyString, CMD_PARAM_NEVER);
910 tmp2 = tmp->AddCommand(wxT("IPFilter"), CMD_ID_GET_IPFILTER, wxTRANSLATE("Get IP filtering preferences."), wxEmptyString, CMD_PARAM_NEVER);
911 tmp3 = tmp2->AddCommand(wxT("State"), CMD_ID_GET_IPFILTER_STATE, wxTRANSLATE("Get IP filtering state for both clients and servers."), wxEmptyString, CMD_PARAM_NEVER);
912 tmp3->AddCommand(wxT("Clients"), CMD_ID_GET_IPFILTER_STATE_CLIENTS, wxTRANSLATE("Get IP filtering state for clients only."), wxEmptyString, CMD_PARAM_NEVER);
913 tmp3->AddCommand(wxT("Servers"), CMD_ID_GET_IPFILTER_STATE_SERVERS, wxTRANSLATE("Get IP filtering state for servers only."), wxEmptyString, CMD_PARAM_NEVER);
914 tmp2->AddCommand(wxT("Level"), CMD_ID_GET_IPFILTER_LEVEL, wxTRANSLATE("Get IP filtering level."), wxEmptyString, CMD_PARAM_NEVER);
916 tmp->AddCommand(wxT("BwLimits"), CMD_ID_GET_BWLIMITS, wxTRANSLATE("Get bandwidth limits."), wxEmptyString, CMD_PARAM_NEVER);
918 tmp = m_commands.AddCommand(wxT("Search"), CMD_ID_SEARCH, wxTRANSLATE("Execute a search."),
919 wxTRANSLATE("A search type has to be specified by giving the type:\n GLOBAL\n LOCAL\n KAD\nExample: 'search kad file' will execute a kad search for \"file\".\n"), CMD_PARAM_ALWAYS);
920 tmp->AddCommand(wxT("global"), CMD_ID_SEARCH_GLOBAL, wxTRANSLATE("Execute a global search."), wxEmptyString, CMD_PARAM_ALWAYS);
921 tmp->AddCommand(wxT("local"), CMD_ID_SEARCH_LOCAL, wxTRANSLATE("Execute a local search"), wxEmptyString, CMD_PARAM_ALWAYS);
922 tmp->AddCommand(wxT("kad"), CMD_ID_SEARCH_KAD, wxTRANSLATE("Execute a kad search"), wxEmptyString, CMD_PARAM_ALWAYS);
924 m_commands.AddCommand(wxT("Results"), CMD_ID_SEARCH_RESULTS, wxTRANSLATE("Show the results of the last search."),
925 wxTRANSLATE("Return the results of the previous search.\n"), CMD_PARAM_NEVER);
927 m_commands.AddCommand(wxT("Progress"), CMD_ID_SEARCH_PROGRESS, wxTRANSLATE("Show the progress of a search."),
928 wxTRANSLATE("Show the progress of a search.\n"), CMD_PARAM_NEVER);
930 m_commands.AddCommand(wxT("Download"), CMD_ID_DOWNLOAD, wxTRANSLATE("Start downloading a file"),
931 wxTRANSLATE("The number of a file from the last search has to be given.\nExample: 'download 12' will start to download the file with the number 12 of the previous search.\n"), CMD_PARAM_ALWAYS);
935 // TODO: These commands below need implementation and/or rewrite!
938 m_commands.AddCommand(wxT("Pause"), CMD_ID_PAUSE, wxTRANSLATE("Pause download."),
939 wxEmptyString, CMD_PARAM_ALWAYS);
941 m_commands.AddCommand(wxT("Resume"), CMD_ID_RESUME, wxTRANSLATE("Resume download."),
942 wxEmptyString, CMD_PARAM_ALWAYS);
944 m_commands.AddCommand(wxT("Cancel"), CMD_ID_CANCEL, wxTRANSLATE("Cancel download."),
945 wxEmptyString, CMD_PARAM_ALWAYS);
947 tmp = m_commands.AddCommand(wxT("Priority"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Set download priority."),
948 wxTRANSLATE("Set priority of a download to Low, Normal, High or Auto.\n"), CMD_PARAM_ALWAYS);
949 tmp->AddCommand(wxT("Low"), CMD_ID_PRIORITY_LOW, wxTRANSLATE("Set priority to low."), wxEmptyString, CMD_PARAM_ALWAYS);
950 tmp->AddCommand(wxT("Normal"), CMD_ID_PRIORITY_NORMAL, wxTRANSLATE("Set priority to normal."), wxEmptyString, CMD_PARAM_ALWAYS);
951 tmp->AddCommand(wxT("High"), CMD_ID_PRIORITY_HIGH, wxTRANSLATE("Set priority to high."), wxEmptyString, CMD_PARAM_ALWAYS);
952 tmp->AddCommand(wxT("Auto"), CMD_ID_PRIORITY_AUTO, wxTRANSLATE("Set priority to auto."), wxEmptyString, CMD_PARAM_ALWAYS);
954 tmp = m_commands.AddCommand(wxT("Show"), CMD_ERR_INCOMPLETE, wxTRANSLATE("Show queues/lists."),
955 wxTRANSLATE("Show upload/download queue, server list or shared files list.\n"), CMD_PARAM_ALWAYS);
956 tmp->AddCommand(wxT("UL"), CMD_ID_SHOW_UL, wxTRANSLATE("Show upload queue."), wxEmptyString, CMD_PARAM_NEVER);
957 tmp->AddCommand(wxT("DL"), CMD_ID_SHOW_DL, wxTRANSLATE("Show download queue."), wxEmptyString, CMD_PARAM_NEVER);
958 tmp->AddCommand(wxT("Log"), CMD_ID_SHOW_LOG, wxTRANSLATE("Show log."), wxEmptyString, CMD_PARAM_NEVER);
959 tmp->AddCommand(wxT("Servers"), CMD_ID_SHOW_SERVERS, wxTRANSLATE("Show servers list."), wxEmptyString, CMD_PARAM_NEVER);
960 // tmp->AddCommand(wxT("Shared"), CMD_ID_SHOW_SHARED, wxTRANSLATE("Show shared files list."), wxEmptyString, CMD_PARAM_NEVER);
962 m_commands.AddCommand(wxT("Reset"), CMD_ID_RESET_LOG, wxTRANSLATE("Reset log."), wxEmptyString, CMD_PARAM_NEVER);
965 // Deprecated commands, kept for backwards compatibility only.
968 #define DEPRECATED(OLDCMD, ID, NEWCMD, PARAM) \
969 m_commands.AddCommand(wxT(OLDCMD), CMD_ID_##ID | CMD_DEPRECATED, CFormat(wxTRANSLATE("Deprecated command, use '%s' instead.")) % wxT(NEWCMD), \
970 CFormat(wxTRANSLATE("This is a deprecated command, and may be removed in the future.\nUse '%s' instead.\n")) % wxT(NEWCMD), CMD_PARAM_##PARAM)
972 DEPRECATED("Stats", STATUS, "Status", NEVER);
973 DEPRECATED("SetIPFilter", SET_IPFILTER, "Set IPFilter", OPTIONAL);
974 DEPRECATED("GetIPLevel", GET_IPFILTER_LEVEL, "Get IPFilter Level", NEVER);
975 DEPRECATED("SetIPLevel", SET_IPFILTER_LEVEL, "Set IPFilter Level", ALWAYS);
976 DEPRECATED("IPLevel", SET_IPFILTER_LEVEL, "Get/Set IPFilter Level", OPTIONAL);
977 DEPRECATED("Servers", SHOW_SERVERS, "Show Servers", NEVER);
978 DEPRECATED("GetBWLimits", GET_BWLIMITS, "Get BwLimits", NEVER);
979 DEPRECATED("SetUpBWLimit", SET_BWLIMIT_UP, "Set BwLimit Up", ALWAYS);
980 DEPRECATED("SetDownBWLimit", SET_BWLIMIT_DOWN, "Set BwLimit Down", ALWAYS);
983 int CamulecmdApp::OnRun()
985 ConnectAndRun(wxT("aMulecmd"), wxT(VERSION));
986 return 0;
989 // Dummy functions for EC logging
990 bool ECLogIsEnabled()
992 return false;
995 void DoECLogLine(const wxString &)
998 // File_checked_for_headers