1 /*****************************************************************************
2  * PokerTH - The open source texas holdem engine                             *
3  * Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May          *
4  *                                                                           *
5  * This program is free software: you can redistribute it and/or modify      *
6  * it under the terms of the GNU Affero General Public License as            *
7  * published by the Free Software Foundation, either version 3 of the        *
8  * License, or (at your option) any later version.                           *
9  *                                                                           *
10  * This program is distributed in the hope that it will be useful,           *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
13  * GNU Affero General Public License for more details.                       *
14  *                                                                           *
15  * You should have received a copy of the GNU Affero General Public License  *
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.     *
17  *                                                                           *
18  *                                                                           *
19  * Additional permission under GNU AGPL version 3 section 7                  *
20  *                                                                           *
21  * If you modify this program, or any covered work, by linking or            *
22  * combining it with the OpenSSL project's OpenSSL library (or a             *
23  * modified version of that library), containing parts covered by the        *
24  * terms of the OpenSSL or SSLeay licenses, the authors of PokerTH           *
25  * (Felix Hammer, Florian Thauer, Lothar May) grant you additional           *
26  * permission to convey the resulting work.                                  *
27  * Corresponding Source for a non-source form of such a combination          *
28  * shall include the source code for the parts of OpenSSL used as well       *
29  * as that of the covered work.                                              *
30  *****************************************************************************/
31 #include "cleanerconfig.h"
32 #include <QtCore>
33 
34 #include <tinyxml.h>
35 
36 #define MODUS 0711
37 
38 #ifdef _WIN32
39 #include <windows.h>
40 #include <direct.h>
41 #endif
42 
43 #include <iostream>
44 #include <sstream>
45 #include <cstdlib>
46 #include <fstream>
47 
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 
51 using namespace std;
52 
53 
CleanerConfig()54 CleanerConfig::CleanerConfig()
55 {
56 	// !!!! Revisionsnummer der Configdefaults !!!!!
57 	configRev = 10;
58 
59 	// Pfad und Dateinamen setzen
60 #ifdef _WIN32
61 	const char *appDataPath = getenv("AppData");
62 	if (appDataPath && appDataPath[0] != 0) {
63 		configFileName = appDataPath;
64 	} else {
65 		const int MaxPathSize = 1024;
66 		char curDir[MaxPathSize + 1];
67 		curDir[0] = 0;
68 		_getcwd(curDir, MaxPathSize);
69 		curDir[MaxPathSize] = 0;
70 		configFileName = curDir;
71 		// Testen ob das Verzeichnis beschreibbar ist
72 		ofstream tmpFile;
73 		const char *tmpFileName = "pokerth_test.tmp";
74 		tmpFile.open((configFileName + "\\" + tmpFileName).c_str());
75 		if (tmpFile) {
76 			// Erfolgreich, Verzeichnis beschreibbar.
77 			// Datei wieder loeschen.
78 			tmpFile.close();
79 			remove((configFileName + "\\" + tmpFileName).c_str());
80 		} else {
81 			// Fehlgeschlagen, Verzeichnis nicht beschreibbar
82 			curDir[0] = 0;
83 			GetTempPathA(MaxPathSize, curDir);
84 			curDir[MaxPathSize] = 0;
85 			configFileName = curDir;
86 		}
87 	}
88 	//define app-dir
89 	configFileName += "\\pokerth\\";
90 	////define log-dir
91 // 	logDir = configFileName;
92 // 	logDir += "log-files\\";
93 
94 	//create directories on first start of app
95 	mkdir(configFileName.c_str());
96 // 	mkdir(logDir.c_str());
97 
98 
99 #else
100 	//define app-dir
101 	const char *homePath = getenv("HOME");
102 	if(homePath) {
103 		configFileName = homePath;
104 		configFileName += "/.pokerth/";
105 		////define log-dir
106 // 		logDir = configFileName;
107 // 		logDir += "log-files/";
108 		//create directories on first start of app
109 		mkdir(configFileName.c_str(), MODUS) ;
110 // 		mkdir(logDir.c_str(), MODUS);
111 
112 	}
113 
114 #endif
115 
116 	ostringstream tempIntToString;
117 	tempIntToString << configRev;
118 
119 	configList.push_back(ConfigInfo("ConfigRevision", CONFIG_TYPE_INT, tempIntToString.str()));
120 	configList.push_back(ConfigInfo("Language", CONFIG_TYPE_STRING, getDefaultLanguage()));
121 
122 	configList.push_back(ConfigInfo("HostAddress", CONFIG_TYPE_STRING, "0.0.0.0"));
123 	configList.push_back(ConfigInfo("DefaultListenPort", CONFIG_TYPE_STRING, "4327"));
124 	configList.push_back(ConfigInfo("ClientAuthString", CONFIG_TYPE_STRING, ""));
125 	configList.push_back(ConfigInfo("ServerAuthString", CONFIG_TYPE_STRING, ""));
126 
127 	configList.push_back(ConfigInfo("WarnLevelToKick", CONFIG_TYPE_INT, "2"));
128 	configList.push_back(ConfigInfo("TextFloodLevelToTrigger", CONFIG_TYPE_INT, "3"));
129 	configList.push_back(ConfigInfo("CapsFloodCapsNumberToTrigger", CONFIG_TYPE_INT, "10"));
130 	configList.push_back(ConfigInfo("LetterRepeatingNumberToTrigger", CONFIG_TYPE_INT, "10"));
131 
132 	configList.push_back(ConfigInfo("KickNumberToBan", CONFIG_TYPE_INT, "2"));
133 	configList.push_back(ConfigInfo("SecondsToForgetAboutKick", CONFIG_TYPE_INT, "1800"));
134 
135 	list<string> badWordsList;
136 	badWordsList.push_back("arsch");
137 	badWordsList.push_back("asshole");
138 	badWordsList.push_back("bastard");
139 	badWordsList.push_back("bitch");
140 	badWordsList.push_back("cunt");
141 	badWordsList.push_back(" dick ");
142 	badWordsList.push_back("drecksau");
143 	badWordsList.push_back(" fag ");
144 	badWordsList.push_back("fagget");
145 	badWordsList.push_back("fotze");
146 	badWordsList.push_back("fuker");
147 	badWordsList.push_back("fuck");
148 	badWordsList.push_back(" fuk ");
149 	badWordsList.push_back("gay");
150 	badWordsList.push_back("horny");
151 	badWordsList.push_back("hure");
152 	badWordsList.push_back("idiot");
153 	badWordsList.push_back("mistgeburt");
154 	badWordsList.push_back("missgeburt");
155 	badWordsList.push_back("motherfucker");
156 	badWordsList.push_back("nazi");
157 	badWordsList.push_back("nigga");
158 	badWordsList.push_back("nigger");
159 	badWordsList.push_back("nutte");
160 	badWordsList.push_back("ommak");
161 	badWordsList.push_back("penis");
162 	badWordsList.push_back("pussy");
163 	badWordsList.push_back("schlampe");
164 	badWordsList.push_back("schwanz");
165 	badWordsList.push_back("sex");
166 	badWordsList.push_back("shit");
167 	badWordsList.push_back("sieg heil");
168 	badWordsList.push_back("slut");
169 	badWordsList.push_back("suck");
170 	badWordsList.push_back("whore");
171 	configList.push_back(ConfigInfo("BadWordsList", CONFIG_TYPE_STRING_LIST, "BadWords", badWordsList));
172 
173 	list<string> badWordsExceptionList;
174 	badWordsExceptionList.push_back("idiots end");
175 	badWordsExceptionList.push_back("all-in-idiot");
176 	badWordsExceptionList.push_back("all-in idiot");
177 	badWordsExceptionList.push_back("allin idiot");
178 	badWordsExceptionList.push_back("all in idiot");
179 	configList.push_back(ConfigInfo("BadWordsException", CONFIG_TYPE_STRING_LIST, "BadWordsException", badWordsExceptionList));
180 
181 
182 	list<string> urlStringsList;
183 	urlStringsList.push_back("http://");
184 	urlStringsList.push_back(".com");
185 	urlStringsList.push_back(".net");
186 	urlStringsList.push_back(".org");
187 	urlStringsList.push_back(".de");
188 	configList.push_back(ConfigInfo("UrlStringsList", CONFIG_TYPE_STRING_LIST, "UrlStrings", urlStringsList));
189 
190 	list<string> urlExceptionStringsList;
191 	urlExceptionStringsList.push_back("http://www.esl.");
192 	urlExceptionStringsList.push_back("http://www.pokerth.net");
193 	urlExceptionStringsList.push_back("pokerth.net");
194 	configList.push_back(ConfigInfo("UrlExceptionStringsList", CONFIG_TYPE_STRING_LIST, "UrlExceptionStrings", urlExceptionStringsList));
195 
196 	//fill tempList firstTime
197 	configBufferList = configList;
198 
199 	configFileName += "cleanerconfig.xml";
200 
201 	//Prüfen ob Configfile existiert --> sonst anlegen
202 	TiXmlDocument doc(configFileName);
203 	if(!doc.LoadFile()) {
204 		myConfigState = NONEXISTING;
205 		updateConfig(myConfigState);
206 	} else {
207 		//Check if config revision is ok. Otherwise --> update()
208 		int tempRevision = 0;
209 
210 		TiXmlHandle docHandle( &doc );
211 		TiXmlElement* confRevision = docHandle.FirstChild( "PokerTHCleaner" ).FirstChild( "Configuration" ).FirstChild( "ConfigRevision" ).ToElement();
212 		if ( confRevision ) {
213 			confRevision->QueryIntAttribute("value", &tempRevision );
214 		}
215 
216 		if (tempRevision < configRev ) { /*löschen()*/
217 			myConfigState = OLD;
218 			updateConfig(myConfigState) ;
219 		}
220 	}
221 
222 
223 	fillBuffer();
224 }
225 
226 
~CleanerConfig()227 CleanerConfig::~CleanerConfig()
228 {
229 }
230 
231 
fillBuffer()232 void CleanerConfig::fillBuffer()
233 {
234 
235 	string tempString1("");
236 	string tempString2("");
237 
238 	TiXmlDocument doc(configFileName);
239 
240 	if(doc.LoadFile()) {
241 		TiXmlHandle docHandle( &doc );
242 
243 		for (size_t i=0; i<configBufferList.size(); i++) {
244 
245 			TiXmlElement* conf = docHandle.FirstChild( "PokerTHCleaner" ).FirstChild( "Configuration" ).FirstChild( configList[i].name ).ToElement();
246 
247 			if ( conf ) {
248 
249 				const char *tmpStr1 = conf->Attribute("value");
250 				if (tmpStr1) tempString1 = tmpStr1;
251 				configBufferList[i].defaultValue = tempString1;
252 
253 				const char *tmpStr2 = conf->Attribute("type");
254 				if (tmpStr2) {
255 					tempString2 = tmpStr2;
256 					if(tempString2 == "list") {
257 
258 						list<string> tempStringList2;
259 
260 						TiXmlElement* confList = docHandle.FirstChild( "PokerTHCleaner" ).FirstChild( "Configuration" ).FirstChild( configList[i].name ).FirstChild().ToElement();
261 
262 						for( ; confList; confList=confList->NextSiblingElement()) {
263 							tempStringList2.push_back(confList->Attribute("value"));
264 						}
265 
266 						configBufferList[i].defaultListValue = tempStringList2;
267 					}
268 				}
269 			} else {
270 				qDebug("Could not find the root element in the config file!");
271 			}
272 		}
273 	}
274 }
275 
writeBuffer() const276 void CleanerConfig::writeBuffer() const
277 {
278 
279 	TiXmlDocument doc;
280 	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "");
281 	doc.LinkEndChild( decl );
282 
283 	TiXmlElement * root = new TiXmlElement( "PokerTHCleaner" );
284 	doc.LinkEndChild( root );
285 
286 	TiXmlElement * config;
287 	config = new TiXmlElement( "Configuration" );
288 	root->LinkEndChild( config );
289 
290 	size_t i;
291 
292 	for (i=0; i<configBufferList.size(); i++) {
293 		TiXmlElement *tmpElement = new TiXmlElement(configBufferList[i].name);
294 		config->LinkEndChild( tmpElement );
295 		tmpElement->SetAttribute("value", configBufferList[i].defaultValue);
296 
297 		if(configBufferList[i].type == CONFIG_TYPE_INT_LIST || configBufferList[i].type == CONFIG_TYPE_STRING_LIST) {
298 
299 			tmpElement->SetAttribute("type", "list");
300 			list<string> tempList = configBufferList[i].defaultListValue;
301 			list<string>::iterator it;
302 			for(it = tempList.begin(); it != tempList.end(); ++it) {
303 
304 				TiXmlElement *tmpSubElement = new TiXmlElement(configBufferList[i].defaultValue);
305 				tmpElement->LinkEndChild( tmpSubElement );
306 				tmpSubElement->SetAttribute("value", *it);
307 			}
308 
309 		}
310 	}
311 	doc.SaveFile( configFileName );
312 
313 }
314 
updateConfig(ConfigState myConfigState)315 void CleanerConfig::updateConfig(ConfigState myConfigState)
316 {
317 
318 	size_t i;
319 
320 	if(myConfigState == NONEXISTING) {
321 
322 		//Create a new ConfigFile!
323 		TiXmlDocument doc;
324 		TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "");
325 		doc.LinkEndChild( decl );
326 
327 		TiXmlElement * root = new TiXmlElement( "PokerTHCleaner" );
328 		doc.LinkEndChild( root );
329 
330 		TiXmlElement * config;
331 		config = new TiXmlElement( "Configuration" );
332 		root->LinkEndChild( config );
333 
334 		for (i=0; i<configList.size(); i++) {
335 			TiXmlElement *tmpElement = new TiXmlElement(configList[i].name);
336 			config->LinkEndChild( tmpElement );
337 			tmpElement->SetAttribute("value", stringToUtf8(configList[i].defaultValue));
338 
339 			if(configList[i].type == CONFIG_TYPE_INT_LIST || configList[i].type == CONFIG_TYPE_STRING_LIST) {
340 
341 				tmpElement->SetAttribute("type", "list");
342 				list<string> tempList = configList[i].defaultListValue;
343 				list<string>::iterator it;
344 				for(it = tempList.begin(); it != tempList.end(); ++it) {
345 
346 					TiXmlElement *tmpSubElement = new TiXmlElement(configList[i].defaultValue);
347 					tmpElement->LinkEndChild( tmpSubElement );
348 					tmpSubElement->SetAttribute("value", *it);
349 				}
350 
351 			}
352 		}
353 
354 		doc.SaveFile( configFileName );
355 	}
356 
357 
358 	if(myConfigState == OLD) {
359 
360 		TiXmlDocument oldDoc(configFileName);
361 
362 		//load the old one
363 		if(oldDoc.LoadFile()) {
364 
365 			string tempString1("");
366 			string tempString2("");
367 
368 			TiXmlDocument newDoc;
369 
370 			//Create the new one
371 			TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "");
372 			newDoc.LinkEndChild( decl );
373 
374 			TiXmlElement * root = new TiXmlElement( "PokerTHCleaner" );
375 			newDoc.LinkEndChild( root );
376 
377 			TiXmlElement * config;
378 			config = new TiXmlElement( "Configuration" );
379 			root->LinkEndChild( config );
380 
381 			//change configRev and AppDataPath
382 			TiXmlElement * confElement0 = new TiXmlElement( "ConfigRevision" );
383 			config->LinkEndChild( confElement0 );
384 			confElement0->SetAttribute("value", configRev);
385 
386 			TiXmlHandle oldDocHandle( &oldDoc );
387 
388 			for (i=0; i<configList.size(); i++) {
389 
390 				TiXmlElement* oldConf = oldDocHandle.FirstChild( "PokerTHCleaner" ).FirstChild( "Configuration" ).FirstChild( configList[i].name ).ToElement();
391 
392 				if ( oldConf ) {
393 					// if element is already there --> take over the saved values
394 
395 					if(configList[i].name != "ConfigRevision") {
396 						// dont update ConfigRevision because it was already set ^
397 
398 						TiXmlElement *tmpElement = new TiXmlElement(configList[i].name);
399 						config->LinkEndChild( tmpElement );
400 
401 						const char *tmpStr1 = oldConf->Attribute("value");
402 						if (tmpStr1) tempString1 = tmpStr1;
403 						tmpElement->SetAttribute("value", tempString1);
404 
405 						//for lists copy elements
406 						const char *tmpStr2 = oldConf->Attribute("type");
407 						if (tmpStr2) {
408 							tempString2 = tmpStr2;
409 							if(tempString2 == "list") {
410 
411 								list<string> tempStringList2;
412 
413 								TiXmlElement* oldConfList = oldDocHandle.FirstChild( "PokerTHCleaner" ).FirstChild( "Configuration" ).FirstChild( configList[i].name ).FirstChild().ToElement();
414 
415 								for( ; oldConfList; oldConfList=oldConfList->NextSiblingElement()) {
416 									tempStringList2.push_back(oldConfList->Attribute("value"));
417 								}
418 
419 								tmpElement->SetAttribute("type", "list");
420 								list<string> tempList = tempStringList2;
421 								list<string>::iterator it;
422 								for(it = tempList.begin(); it != tempList.end(); ++it) {
423 
424 									TiXmlElement *tmpSubElement = new TiXmlElement(tempString1);
425 									tmpElement->LinkEndChild( tmpSubElement );
426 									tmpSubElement->SetAttribute("value", *it);
427 								}
428 							}
429 						}
430 					}
431 				} else {
432 					// if element is not there --> set it with defaultValue
433 					TiXmlElement *tmpElement = new TiXmlElement(configList[i].name);
434 					config->LinkEndChild( tmpElement );
435 					tmpElement->SetAttribute("value", stringToUtf8(configList[i].defaultValue));
436 
437 					if(configList[i].type == CONFIG_TYPE_INT_LIST || configList[i].type == CONFIG_TYPE_STRING_LIST) {
438 
439 						tmpElement->SetAttribute("type", "list");
440 						list<string> tempList = configList[i].defaultListValue;
441 						list<string>::iterator it;
442 						for(it = tempList.begin(); it != tempList.end(); ++it) {
443 
444 							TiXmlElement *tmpSubElement = new TiXmlElement(configList[i].defaultValue);
445 							tmpElement->LinkEndChild( tmpSubElement );
446 							tmpSubElement->SetAttribute("value", *it);
447 						}
448 					}
449 				}
450 			}
451 			newDoc.SaveFile( configFileName );
452 		} else {
453 			qDebug("Cannot update config file: Unable to load configuration.");
454 		}
455 
456 
457 	}
458 }
459 
readConfigString(string varName) const460 string CleanerConfig::readConfigString(string varName) const
461 {
462 
463 	size_t i;
464 	string tempString("");
465 
466 	for (i=0; i<configBufferList.size(); i++) {
467 
468 		if (configBufferList[i].name == varName) {
469 			tempString = configBufferList[i].defaultValue;
470 		}
471 	}
472 
473 	return tempString;
474 }
475 
readConfigInt(string varName) const476 int CleanerConfig::readConfigInt(string varName) const
477 {
478 
479 	size_t i;
480 	string tempString("");
481 	int tempInt=0;
482 
483 	for (i=0; i<configBufferList.size(); i++) {
484 
485 		if (configBufferList[i].name == varName) {
486 			tempString = configBufferList[i].defaultValue;
487 		}
488 	}
489 
490 	istringstream isst;
491 	isst.str (tempString);
492 	isst >> tempInt;
493 
494 	return tempInt;
495 }
496 
readConfigStringList(string varName) const497 list<string> CleanerConfig::readConfigStringList(string varName) const
498 {
499 
500 	size_t i;
501 	list<string> tempStringList;
502 
503 	for (i=0; i<configBufferList.size(); i++) {
504 
505 		if (configBufferList[i].name == varName) {
506 			tempStringList = configBufferList[i].defaultListValue;
507 		}
508 	}
509 
510 	return tempStringList;
511 }
512 
513 
readConfigIntList(string varName) const514 list<int> CleanerConfig::readConfigIntList(string varName) const
515 {
516 
517 	size_t i;
518 	list<string> tempStringList;
519 	list<int> tempIntList;
520 
521 	for (i=0; i<configBufferList.size(); i++) {
522 
523 		if (configBufferList[i].name == varName) {
524 			tempStringList = configBufferList[i].defaultListValue;
525 		}
526 	}
527 
528 	istringstream isst;
529 	int tempInt;
530 	list<string>::iterator it;
531 	for(it = tempStringList.begin(); it != tempStringList.end(); ++it) {
532 
533 		isst.str(*it);
534 		isst >> tempInt;
535 		tempIntList.push_back(tempInt);
536 		isst.str("");
537 		isst.clear();
538 	}
539 
540 	return tempIntList;
541 }
542 
543 
writeConfigInt(string varName,int varCont)544 void CleanerConfig::writeConfigInt(string varName, int varCont)
545 {
546 
547 	size_t i;
548 	ostringstream intToString;
549 
550 	for (i=0; i<configBufferList.size(); i++) {
551 
552 		if (configBufferList[i].name == varName) {
553 			intToString << varCont;
554 			configBufferList[i].defaultValue = intToString.str();
555 		}
556 	}
557 }
558 
559 
writeConfigIntList(string varName,list<int> varCont)560 void CleanerConfig::writeConfigIntList(string varName, list<int> varCont)
561 {
562 
563 	size_t i;
564 	ostringstream intToString;
565 	list<string> stringList;
566 
567 	for (i=0; i<configBufferList.size(); i++) {
568 
569 		if (configBufferList[i].name == varName) {
570 			list<int>::iterator it;
571 			for(it = varCont.begin(); it != varCont.end(); ++it) {
572 
573 				intToString << (*it);
574 				stringList.push_back(intToString.str());
575 				intToString.str("");
576 				intToString.clear();
577 			}
578 
579 			configBufferList[i].defaultListValue = stringList;
580 		}
581 	}
582 }
583 
writeConfigStringList(string varName,list<string> varCont)584 void CleanerConfig::writeConfigStringList(string varName, list<string> varCont)
585 {
586 
587 	size_t i;
588 
589 	for (i=0; i<configBufferList.size(); i++) {
590 
591 		if (configBufferList[i].name == varName) {
592 
593 			configBufferList[i].defaultListValue = varCont;
594 		}
595 	}
596 }
597 
writeConfigString(string varName,string varCont)598 void CleanerConfig::writeConfigString(string varName, string varCont)
599 {
600 
601 	size_t i;
602 	for (i=0; i<configBufferList.size(); i++) {
603 		if (configBufferList[i].name == varName) {
604 			configBufferList[i].defaultValue = varCont;
605 		}
606 	}
607 
608 }
stringToUtf8(const std::string & myString)609 std::string CleanerConfig::stringToUtf8(const std::string &myString)
610 {
611 
612 	QString tmpString = QString::fromStdString(myString);
613 	std::string myUtf8String = tmpString.toUtf8().constData();
614 
615 	return myUtf8String;
616 }
617 
stringFromUtf8(const std::string & myString)618 std::string CleanerConfig::stringFromUtf8(const std::string &myString)
619 {
620 	QString tmpString = QString::fromUtf8(myString.c_str());
621 
622 	return tmpString.toStdString();
623 }
624 
getDefaultLanguage()625 std::string CleanerConfig::getDefaultLanguage()
626 {
627 	return QLocale::system().name().toStdString();
628 }
629