//to is also included inline Days dayRange(Day from, Day to) { Days days; while (from <= to) { days.push_back(from); ++from; } return days; }
//Returns a vector of nr days starting from today, only including mon ... fri inline Days workDays(size_t nr) { Days days; auto t = std::time(0); auto gt = std::gmtime(&t); Day d(gt->tm_year+1900, gt->tm_mon+1, gt->tm_mday); int wday = (gt->tm_wday+6)%7;//wday == 0 => monday while (days.size() < nr) { if (wday < 5) //mon .. fri days.push_back(d); ++d; wday = (wday+1)%7; } return days; }
Date operator +(const Date& date, const Days& days) { return detail::EpochDaysToDate(detail::DateToEpochDays(date) + days.count()); }
int main() { // Day, Month, Year are just type-safe wrappers for unsigned int Days myday; assert(myday.value() == 0); Months mymonth(12); assert(mymonth.value() == 12); // have you declared your getters const??? :-) const Years CONST_YEAR(2012); assert(CONST_YEAR.value() == 2012); // test implicit conversion to unsigned int (operator unsigned int()) assert(0 == myday); assert(12 == mymonth); assert(2012 == CONST_YEAR); // static member function Date::daysInMonth() int days_feb = Date::daysInMonth(2); cout << "February normally has " << days_feb << " days." << endl; assert(days_feb == 28); int days_feb_2400 = Date::daysInMonth(Months(2),Years(2400)); cout << "In year 2400, February will have " << days_feb_2400 << " days." << endl; assert(days_feb_2400 == 29); // Date constructor, getters, and stream output Date d1; cout << "Date1: " << d1 << endl; assert(d1.day() == 0); assert(d1.month() == 0); assert(d1.year() == 0); // comparison of two dates Date d2(1, 1, 2013); cout << "Date2: " << d2 << endl; Date d3(28, 2, 2013); cout << "Date3: " << d3 << endl; cout << "Date2 == Date3: " << (d2==d3) << endl; assert(! (d2 == d3)); cout << "Date2 != Date3: " << (d2!=d3) << endl; assert(d2 != d3); cout << "Date2 < Date3: " << (d2<d3) << endl; assert(d2<d3); cout << "Date3 < Date3: " << (d3<d2) << endl; assert(!(d3<d2)); // static member function Date::isLeapYear() cout << "Is 1999 a leap year: " << Date::isLeapYear(1999) << endl; assert(!Date::isLeapYear(1999)); cout << "Is 2000 a leap year: " << Date::isLeapYear(2000) << endl; assert(Date::isLeapYear(2000)); cout << "Is 2100 a leap year: " << Date::isLeapYear(2100) << endl; assert(!Date::isLeapYear(2100)); Date d4(28, 2, 2013); // add one day d4 += Days(1); cout << "Date3 +1d: " << d4 << endl; assert(d4 == Date(1,3,2013)); // add many days (multiple months) int manydays = 31+30+31+30+31+31; // March ... August d4 += Days(manydays); cout << "Date3 +" << manydays << "d: " << d4 << endl; assert(d4 == Date(1,9,2013)); // does += return the correct return type and value? Date x(1,1,2012); Date y = x+=Days(4); // should work!!!// Fehler!!! cout << x << " + 4d = " << y <<endl; assert(x == Date(5,1,2012)); Date d5(1,1,2015); // add months Months m3 = d5.month(); d5 += Months(2); cout << "Date3 +2m:" << d5 << endl; assert(d5.month() == m3+2); // add years Years y3 = d5.year(); d5 += Years(20); cout << "Date3 +20y:" << d5 << endl; assert(d5.year() == y3+20); // verifizieren Sie, dass die folgende Zeile NICHT compiliert, // und kommentieren Sie sie dann aus // d5 += 1; // non-mutating addition operators const Date dd(31,12,2012); Date dd2 = dd + Days(1); cout << dd << " + 1 day = " << dd2 << endl; assert(dd2 == Date(1,1,2013)); Date dd3 = dd + Months(4); cout << dd << " + 4 months = " << dd3 << endl; assert(dd3 == Date(30,4,2013)); Date dd4 = dd + Years(1000); cout << dd << " + 1000 years = " << dd4 << endl; assert(dd4 == Date(31,12,3012)); // mixed units Date dd5 = dd + Days(2) + Months(3) + Years(5); cout << dd << " + 2d + 3m + 5y = " << dd5 << endl; assert(dd5 == Date(2,4,2018)); cout << " " << endl; cout << " " << endl; cout << " Map-Test-Area " << endl; cout << " " << endl; Date date1(1,5,2013); Date date2(6,12,2013); Date date3(2,4,2013); Date date4(6,4,2013); Date date5(5,5,2013); Date date6(5,4,2013); Date date7(7,4,2013); Date date8(8,4,2013); //MyDate::Map map1; MyTemplate::Map<Date,string> map1; map1[date1] = "Wenig Arbeit, viele Demos"; map1[date2] = "Nikolaus kommt"; assert(map1.size() == 2); map1[date2] = "Nikolaus kommt doch nicht"; assert(map1.size() == 2); assert(map1.getRootNode()->m_right->m_pair.first == date2); map1[date3] = "der 02.04.2013"; map1[date4] = "der 06.04.2013"; map1[date5] = "der 05.05.2013"; map1[date6] = "der 05.04.2013"; map1[date7] = "der 07.04.2013"; assert(map1.size() == 7); // tier 1 rechts assert(map1.m_root->contains(date2)); // tier 1 links assert(map1.m_root->contains(date3)); // tier 3 links assert(map1.m_root->contains(date7)); // nicht in der map assert(!map1.m_root->contains(date8)); // Abfrage der Position der Daten in der map1 assert(map1.m_root->m_pair.first == date1); assert(map1.m_root->m_left->m_pair.first == date3); assert(map1.m_root->m_right->m_pair.first == date2); assert(map1.m_root->m_left->m_right->m_pair.first == date4); assert(map1.m_root->m_right->m_left->m_pair.first == date5); assert(map1.m_root->m_left->m_right->m_left->m_pair.first == date6); assert(map1.m_root->m_left->m_right->m_right->m_pair.first == date7); cout << " Unsere Map an dieser Stelle " << endl; cout << " " << endl; cout << " [1,5,2013] " << endl; cout << " | " << endl; cout << " _______________________|__________________ " << endl; cout << " | | " << endl; cout << " | | " << endl; cout << " [2,4,2013] [6,12,2013] " << endl; cout << " | | " << endl; cout << " |___________ ___________| " << endl; cout << " | | " << endl; cout << " | | " << endl; cout << " [6,4,2013] [5,5,2013] " << endl; cout << " | " << endl; cout << " ______|______ " << endl; cout << " | | " << endl; cout << " | | " << endl; cout << " [5,4,2013] [7,4,2013] " << endl; cout << " " << endl; MyTemplate::Map<Date,string> map2; // Zuweisungsoperator Test map2=map1; assert(map2.size() == 7); // Abfrage der Position der Daten in der map2 assert(map2.m_root->m_pair.first == date1); assert(map2.m_root->m_left->m_pair.first == date3); assert(map2.m_root->m_right->m_pair.first == date2); assert(map2.m_root->m_left->m_right->m_pair.first == date4); assert(map2.m_root->m_right->m_left->m_pair.first == date5); assert(map2.m_root->m_left->m_right->m_left->m_pair.first == date6); assert(map2.m_root->m_left->m_right->m_right->m_pair.first == date7); map2.m_root->m_right->m_pair.second = "Darf nicht in map1 stehen!"; assert(&map1.m_root->m_right->m_pair != &map2.m_root->m_right->m_pair); assert(map2.m_root->m_right->m_pair.second == "Darf nicht in map1 stehen!"); assert(map1.m_root->m_right->m_pair.second != "Darf nicht in map1 stehen!"); // Copy-Konstruktor-Test MyTemplate::Map<Date,string> map3(map1); assert(map3.m_root->m_pair.first == date1); assert(map3.m_root->m_left->m_pair.first == date3); assert(map3.m_root->m_right->m_pair.first == date2); assert(map3.m_root->m_left->m_right->m_pair.first == date4); assert(map3.m_root->m_right->m_left->m_pair.first == date5); assert(map3.m_root->m_left->m_right->m_left->m_pair.first == date6); assert(map3.m_root->m_left->m_right->m_right->m_pair.first == date7); map3.m_root->m_right->m_pair.second = "Darf nicht in map1 stehen!"; assert(&map1.m_root->m_right->m_pair != &map3.m_root->m_right->m_pair); assert(map3.m_root->m_right->m_pair.second == "Darf nicht in map1 stehen!"); assert(map1.m_root->m_right->m_pair.second != "Darf nicht in map1 stehen!"); const MyTemplate::Map<Date,string>& constMap = map3; constMap[date1]; // Templateparameter int/string Test MyTemplate::Map<int, string> map4; map4[23]= "was"; assert(map4.m_root->m_pair.second=="was"); // Templateparameter string/string Test MyTemplate::Map<string, string> map5; map5["key"]= "wieso"; assert(map5.m_root->m_pair.second=="wieso"); // Iterator Copyconstructor Test MyTemplate::Map<Date,string>::Iterator it(map1.m_root); MyTemplate::Map<Date,string>::Iterator it1; // Iterator Zuweisungsoperator Test it1 = it; // Test auf Gleichheit assert(it1 == it); // Test auf Ungleichheit assert(!(it1 != it)); // Dereferenzierung mittels * Test pair<Date,string> a = *it; assert(a.second == "Wenig Arbeit, viele Demos"); // Dereferenzierung mittels -> Test assert(it1->second == "Wenig Arbeit, viele Demos"); // Inkrement Test it = it++; assert(it->second == "der 05.05.2013"); // Map::begin() Test it = map1.begin(); assert(it->second == "der 02.04.2013"); // Aufgabenblatt Test Beispiel MyTemplate::Map<int,string> m; m[4] = "vier"; m[7] = "sieben"; m[2] = "zwei"; MyTemplate::Map<int,string>::Iterator i = m.begin(); cout << "kleinstes Element: " << i->first << "/" << i->second << endl; cout << "weitere Elemente, sortiert: " << endl; while(i!=m.end()) { pair<int,string> p = *i; cout << " " << p.first << "/" << p.second << endl; i++; // nach hinten verlagert, wahrscheinlich hier korrekt. } m.begin()->second = "neuer Wert"; // hier darf kein wert nachgetragen werden. // m.begin()->first = 2; cout << ""<< endl; cout << "Mapped_t ist nun ein anderer Paramenter als string: "<< endl; MyTemplate::Map<int,float> mm; mm[4] = 4.5f; mm[5] = 2.8923f; MyTemplate::Map<int,float>::Iterator ii = mm.begin(); cout << "kleinstes Element: " << ii->first << "/" << ii->second << endl; #if 0 #endif cout << "" << endl; cout << "all tests completed." << endl; cout << "" << endl; return 0; }
int main() { { Months months(23); cout << months.getValue() << " months" << endl; Days days = months; cout << days.getValue() << " days" << endl; Hours hrs(months); cout << hrs.getValue() << " hrs." << endl; Minutes m(hrs); cout << m.getValue() << " min." << endl; Seconds s(m); cout << s.getValue() << " sec." << endl; Milliseconds ms; ms = s; cout << ms.getValue() << " ms" << endl; } cout << "---------------------\n"; { Minutes min(10); cout << min.getValue() << " min. " << endl; Seconds sec = min; cout << sec.getValue() << " sec. " << endl; } cout << "---------------------\n"; { Miles miles(24859); //circumfrence of the Earth cout << miles.getValue() << " miles" << endl; Yards yards(miles); cout << yards.getValue() << " yd." << endl; Feet feet(miles); cout << feet.getValue() << " ft." << endl; Inches inches(miles); cout << inches.getValue() << " in." << endl; } cout << "---------------------\n"; { Minutes minutes(1000000ULL); Yards yards(minutes); cout << "There are " << (yards.getValue()/1000000.0) << " yards in a minute!\n"; } cout << "---------------------\n"; { Inches inches; Feet feet; Yards yards; string s = "12 12 12"; std::istringstream iss(s); iss >> inches >> feet >> yards; cout << inches << ' ' << feet << ' ' << yards << endl; cout << inches << ' ' << ((Inches)feet) << ' ' << ((Inches)yards) << endl; } cout << "---------------------\n"; { Radians r; r = 3.14159; cout << r << " radians is " << (Degrees)r << " degrees\n"; Degrees d(r); Degrees d2; d2 = r; cout << (Degrees)r << " == " << d << " == " << d2 << endl; } system("PAUSE"); return 0; }
int main() { cout << "Starting Unit Tests for Day, Month, Year, Date..." << endl; { // Day, Month, Year are just type-safe wrappers for unsigned int Days myday; assert(myday.value() == 0); Months mymonth(12); assert(mymonth.value() == 12); // have you declared your getters const??? :-) const Years CONST_YEAR(2012); assert(CONST_YEAR.value() == 2012); // test implicit conversion to unsigned int (operator unsigned int()) assert(0 == myday); assert(12 == mymonth); assert(2012 == CONST_YEAR); Date x(1,1,2012); assert(x.daysInMonth(Months(2),Years(2012)).value()==29); } { // static member function Date::daysInMonth() int days_feb = Date::daysInMonth(2); cout << "February normally has " << days_feb << " days." << endl; assert(days_feb == 28); int days_feb_2400 = Date::daysInMonth(Months(2),Years(2400)); cout << "In year 2400, February will have " << days_feb_2400 << " days." << endl; assert(days_feb_2400 == 29); } { // Date constructor, getters, and stream output Date d1; cout << "Date1: " << d1 << endl; assert(d1.day() == 0); assert(d1.month() == 0); assert(d1.year() == 0); } { // comparison of two dates Date d2(1, 1, 2013); cout << "Date2: " << d2 << endl; Date d3(28, 2, 2013); cout << "Date3: " << d3 << endl; cout << "Date2 == Date3: " << (d2==d3) << endl; assert(! (d2 == d3)); cout << "Date2 != Date3: " << (d2!=d3) << endl; assert(d2 != d3); cout << "Date2 < Date3: " << (d2<d3) << endl; assert(d2<d3); cout << "Date3 < Date3: " << (d3<d2) << endl; assert(!(d3<d2)); } { // static member function Date::isLeapYear() cout << "Is 1999 a leap year: " << Date::isLeapYear(1999) << endl; assert(!Date::isLeapYear(1999)); cout << "Is 2000 a leap year: " << Date::isLeapYear(2000) << endl; assert(Date::isLeapYear(2000)); cout << "Is 2100 a leap year: " << Date::isLeapYear(2100) << endl; assert(!Date::isLeapYear(2100)); } { Date d3(28, 2, 2013); // add one day d3 += Days(1); cout << "Date3 +1d: " << d3 << endl; assert(d3 == Date(1,3,2013)); // add many days (multiple months) int manydays = 31+30+31+30+31+31; // March ... August d3 += Days(manydays); cout << "Date3 +" << manydays << "d: " << d3 << endl; assert(d3 == Date(1,9,2013)); // add more days (so year is changed) int evenmoredays = 480; d3 += Days(evenmoredays); cout << "Date3 +" << evenmoredays << "d: " << d3 << endl; assert(d3.year() == 2014); // does += return the correct return type and value? Date x(1,1,2012); Date y = x+=Days(4); // should work!!! cout << x << " + 4d = " << y <<endl; assert(x == Date(5,1,2012)); } { Date d3(1,1,2015); // add months Months m3 = d3.month(); d3 += Months(2); cout << "Date3 +2m:" << d3 << endl; assert(d3.month() == m3+2); // add years Years y3 = d3.year(); d3 += Years(20); cout << "Date3 +20y:" << d3 << endl; assert(d3.year() == y3+20); // verifizieren Sie, dass die folgende Zeile NICHT compiliert, // und kommentieren Sie sie dann aus d3 += 1; // er compliert aber ändert nichts am objekt } { // non-mutating addition operators const Date dd(31,12,2012); Date dd2 = dd + Days(1); cout << dd << " + 1 day = " << dd2 << endl; assert(dd2 == Date(1,1,2013)); Date dd3 = dd + Months(4); cout << dd << " + 4 months = " << dd3 << endl; assert(dd3 == Date(30,4,2013)); Date dd4 = dd + Years(1000); cout << dd << " + 1000 years = " << dd4 << endl; assert(dd4 == Date(31,12,3012)); // mixed units Date dd5 = dd + Days(2) + Months(3) + Years(5); cout << dd << " + 2d + 3m + 5y = " << dd5 << endl; assert(dd5 == Date(2,4,2018)); } { cout << "From here on 2.2" << endl; Date d1(27,5,2013); Date d2(27,6,2013); Date d3(6,7,2014); Date d4(13,2,2012); Date d5(1,1,2000); Date d6(13,3,2012); Date d7(29,5,2013); cout << "The Dates:" << endl; cout << d1 << endl; cout << d2 << endl; cout << d3 << endl; cout << d4 << endl; cout << d5 << endl; cout << d6 << endl; cout << d7 << endl; MyDate::Map m; m[d1]; cout << "Should be 1 is: " << m[d1] << endl; m[d2]; m[d3]; m[d4]; m[d5]; m[d6]; m[d7]; cout << "Should be 5 is: " << m[d5] << endl; cout << "Change message of " << d2 << " to 19" << endl; m.setMessage(d2,19); cout << "Should be 19 is: " << m[d2] << endl; cout << "Map contains " << d3 << ", should be 1 is: " << m.contains(*m.getRootNode(), d3) << endl; cout << "Map clone to const Map begins" << endl; const MyDate::Map mc = m; const Date dc1(13,2,2012); const Date dc2(25,3,2000); cout << "New Dates are:" << endl; cout << dc1 << endl; cout << dc2 << endl; cout << "Should be 4 is: " << mc[dc1] << endl; cout << "Should be not in List" << mc[dc2] << endl; } { cout << "From here on Nr 2.3" << endl; templateSpace::Map<int,std::string> m; m[0] = "hallo"; m[1] = "bla"; m[2] = "blub"; assert(m[0] == "hallo"); assert(m[1] == "bla"); cout << "should be hallo is " << m[0] << endl; cout << "should be bla is " << m[1] << endl; cout << "From here on Nr 2.3 Iterator\n" << endl; cout << "Starting i++ Iteration:\n"<< endl; for (templateSpace::Map<int,std::string>::Iterator i(m.begin()); i != m.end(); ++i) { cout << i.key() << ": " << i.value() << endl; } cout << "\n=====================\n"<< endl; } cout << "all tests completed." << endl; cout << "Cya, I'm done here" << endl; return 0; }
int main () { auto system_start = chrono::system_clock::now(); /** Durations */ chrono::duration<int> twentySeconds(20); // Базова ЕИ - секунда cout << twentySeconds.count() << endl; /** Используем рациональные числа, с целью представления значений duration в других ЕИ времени */ chrono::duration<double,ratio<60>> halfAMinute(0.5); // 0.5 * ratio<60,1> cout << halfAMinute.count() << endl; chrono::duration<long,ratio<1,1000>> oneMillisecond(1); cout << oneMillisecond.count() << endl; // Вывод: 29999 ms cout << "diff: " << (halfAMinute - oneMillisecond).count() << " ms" << endl; /** По аналогии опредеены и типы пространства имен chrono */ /** Например: typedef duration<signed int-type>=29 bits, ratio<60>> minutes; */ chrono::minutes threeHours(180); // Три часа cout << chrono::duration_cast<chrono::hours>(threeHours).count() << "hours" << endl; // Выполняем печать с помощью перегруженной функции chrono::hours hh = chrono::duration_cast<chrono::hours>(threeHours); cout << "180 minutes is = " << hh << endl; /** Приведение вещественных значенией интервала */ chrono::seconds ss = chrono::duration_cast<chrono::seconds>(halfAMinute); cout << "half a minute is " << halfAMinute << endl; /** Разложение интервала на hh::mm::ss */ chrono::milliseconds ms(7255101); chrono::hours h1 = chrono::duration_cast<chrono::hours>(ms); chrono::minutes m1 = chrono::duration_cast<chrono::minutes>(ms % chrono::hours(1)); chrono::seconds s1 = chrono::duration_cast<chrono::seconds>(ms % chrono::minutes(1)); chrono::milliseconds ms1 = chrono::duration_cast<chrono::milliseconds>(ms % chrono::seconds(1)); cout << ms.count() << " ms is " << setfill('0') << setw(2) << h1.count() << "::" << setw(2) << m1.count() << "::" << setw(2) << s1.count() << "::" << setw(3) << ms1.count() << endl; /** Clocks and timepoints */ cout << endl; cout << "\nsystem_clock: " << endl; printClockData<chrono::system_clock>(); cout << "\nhigh_resolution_clock: " << endl; printClockData<chrono::high_resolution_clock>(); cout << "\nsteady_clock: " << endl; printClockData<chrono::steady_clock>(); // Даем нагрузку for (int i = 0; i < 10000000; i++) { continue; } // Время провдолжительности работы программы auto diff = chrono::system_clock::now() - system_start; auto sec = chrono::duration_cast<chrono::milliseconds>(diff); cout << "Program runs: " << sec.count() << " ms" << endl; /** Timepoints */ // Печатаем начало времен для системных часов chrono::system_clock::time_point tp; cout << "epoch: " << asString(tp) << endl; // Печатаем текущее время tp = chrono::system_clock::now(); cout << "now: " << asString(tp) << endl; // Печатаем предел слева для часов системного времени tp = chrono::system_clock::time_point::min(); cout << "min: " << asString(tp) << endl; // Печатаем предел справа для часов системного времени tp = chrono::system_clock::time_point::max(); cout << "max: " << asString(tp) << endl; /** Timepoint arithmetics */ // Определяем период равный одному дню typedef chrono::duration<int,ratio<24*3600>> Days; // Определяем значение времени по системным часам chrono::time_point<chrono::system_clock> tp_1; // Эквивалентно system_clock::time_point cout << "epoch: " << asString(tp_1) << endl; // Добавляем один день 23 часа и 55 миут tp_1 += Days(1) + chrono::hours(23) + chrono::minutes(55); cout << "later: "<< asString(tp_1) << endl; // Вычисляем разницу в минутах и днях diff = tp_1 - chrono::system_clock::time_point(); cout << "diff: " << chrono::duration_cast<chrono::minutes>(diff).count() << " minutes." << endl; // Преобразуем относительно введенного нами типа данных Days days = chrono::duration_cast<Days>(diff); cout << "diff: " << days.count() << "day(s)" << endl; // Вычитаем один год (предположительно вычитаемый год является высокосным) tp_1 -= chrono::hours(24*365); cout << "-1 year: " << asString(tp_1) << endl; // Вычисляем 50 лет (утрируем и считаем год равным 365 дням) tp_1 -= chrono::duration<int,ratio<3600*24*365>>(50); cout << "-50 years: " << asString(tp_1) << endl; // Еще раз вычитаем 50 лет tp_1 -= chrono::duration<int,ratio<3600*24*365>>(50); cout << "-50 years: " << asString(tp_1) << endl; /** timepoint/calendar conversion */ auto tp_m1 = makeTimePoint(2010,01,01,00,00); cout << "Make timepoint(1): " << asString(tp_m1) << endl; auto tp_m2 = makeTimePoint(2011,05,23,13,44); cout << "Make timepoint(2):" << asString(tp_m2) << endl; // Добавляем 50 лет к созданной точке времени tp_m1 += chrono::duration<int,ratio<3600*24*365>>(50); cout << "Add to timepoint(1) 50 years: " << asString(tp_m1) << endl; exit(EXIT_SUCCESS); }
inline void Formatter(FormatData& formatData, const Days& days) { Formatter(formatData, days.count()); formatData.string.push_back(U'd'); }
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg) { if(server.game().getGameState() == GAME_STATE_SHUTDOWN) { getConnection()->close(); return false; } uint32_t clientIp = getConnection()->getIP(); /*uint16_t operatingSystem = msg.GetU16();*/msg.SkipBytes(2); uint16_t version = msg.GetU16(); msg.SkipBytes(12); if(!RSA_decrypt(msg)) { getConnection()->close(); return false; } uint32_t key[4] = {msg.GetU32(), msg.GetU32(), msg.GetU32(), msg.GetU32()}; enableXTEAEncryption(); setXTEAKey(key); std::string name = msg.GetString(), password = msg.GetString(); if(name.empty()) { if(!server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER)) { disconnectClient(0x0A, "Invalid account name."); return false; } name = "1"; password = "******"; } if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { disconnectClient(0x0A, CLIENT_VERSION_STRING); return false; } if(server.game().getGameState() < GAME_STATE_NORMAL) { disconnectClient(0x0A, "Server is just starting up, please wait."); return false; } if(server.game().getGameState() == GAME_STATE_MAINTAIN) { disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while."); return false; } if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId)) { disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later."); return false; } if(IOBan::getInstance()->isIpBanished(clientIp)) { disconnectClient(0x0A, "Your IP is banished!"); return false; } uint32_t id = 1; if(!IOLoginData::getInstance()->getAccountId(name, id)) { ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false); disconnectClient(0x0A, "Invalid account name."); return false; } AccountP account = IOLoginData::getInstance()->loadAccount(id); if (account == nullptr) { disconnectClient(0x0A, "Invalid account name."); return false; } if(!encryptTest(password, account->getPassword())) { ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false); disconnectClient(0x0A, "Invalid password."); return false; } Ban ban; ban.value = account->getId(); ban.type = BAN_ACCOUNT; if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account->getId(), PlayerFlag_CannotBeBanned)) { bool deletion = ban.expires < 0; std::string name_ = "Automatic "; if(!ban.adminId) name_ += (deletion ? "deletion" : "banishment"); else IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true); char buffer[500 + ban.comment.length()]; sprintf(buffer, "Your account has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.", (deletion ? "deleted" : "banished"), formatDateShort(ban.added).c_str(), name_.c_str(), getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(), (deletion ? "account won't be undeleted" : "banishment will be lifted at:\n"), (deletion ? "." : formatDateShort(ban.expires, true).c_str())); disconnectClient(0x0A, buffer); return false; } const Account::Characters& characters = account->getCharacters(); if(!server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER) && characters.empty()) { disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the " + server.configManager().getString(ConfigManager::SERVER_NAME) + " website at " + server.configManager().getString(ConfigManager::URL) + ".").c_str()); return false; } ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true); if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false)) { TRACK_MESSAGE(output); output->AddByte(0x14); char motd[1300]; sprintf(motd, "%d\n%s", server.game().getMotdId(), server.configManager().getString(ConfigManager::MOTD).c_str()); output->AddString(motd); uint32_t serverIp = serverIps[0].first; for(IpList::iterator it = serverIps.begin(); it != serverIps.end(); ++it) { if((it->first & it->second) != (clientIp & it->second)) continue; serverIp = it->first; break; } //Add char list output->AddByte(0x64); if(server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER) && id != 1) { output->AddByte(characters.size() + 1); output->AddString("Account Manager"); output->AddString(server.configManager().getString(ConfigManager::SERVER_NAME)); output->AddU32(serverIp); output->AddU16(server.configManager().getNumber(ConfigManager::GAME_PORT)); } else output->AddByte((uint8_t)characters.size()); for (auto it = characters.cbegin(); it != characters.cend(); ++it) { auto& character = *it; #ifndef __LOGIN_SERVER__ output->AddString(character->getName()); output->AddString(character->getType()); output->AddU32(serverIp); output->AddU16(server.configManager().getNumber(ConfigManager::GAME_PORT)); #else if(version < it->second->getVersionMin() || version > it->second->getVersionMax()) continue; output->AddString(it->first); output->AddString(it->second->getName()); output->AddU32(it->second->getAddress()); output->AddU16(it->second->getPort()); #endif } Days premiumDays = account->getPremiumDays(); if (premiumDays.count() >= std::numeric_limits<uint16_t>::max()) { output->AddU16(std::numeric_limits<uint16_t>::max()); } else { output->AddU16(static_cast<uint16_t>(premiumDays.count())); } OutputMessagePool::getInstance()->send(output); } getConnection()->close(); return true; }