Updated Copyright year to 2013
[getmangos.git] / src / realmd / RealmList.cpp
blobf9a68a93be785aa03b57ff992d97a5f4613c369e
1 /*
2 * Copyright (C) 2005-2013 MaNGOS <http://getmangos.com/>
4 * This program 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.
9 * This program 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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /** \file
20 \ingroup realmd
23 #include "Common.h"
24 #include "RealmList.h"
25 #include "AuthCodes.h"
26 #include "Util.h" // for Tokens typedef
27 #include "Policies/SingletonImp.h"
28 #include "Database/DatabaseEnv.h"
30 INSTANTIATE_SINGLETON_1(RealmList);
32 extern DatabaseType LoginDatabase;
34 // will only support WoW 1.12.1/1.12.2, WoW:TBC 2.4.3, WoW:WotLK 3.3.5a and official release for WoW:Cataclysm and later, client builds 15595, 10505, 8606, 6005, 5875
35 // if you need more from old build then add it in cases in realmd sources code
36 // list sorted from high to low build and first build used as low bound for accepted by default range (any > it will accepted by realmd at least)
38 static RealmBuildInfo ExpectedRealmdClientBuilds[] =
40 {15595, 4, 3, 4, ' '}, // highest supported build, also auto accept all above for simplify future supported builds testing
41 {15050, 4, 3, 0, ' '},
42 {13623, 4, 0, 6, 'a'},
43 {12340, 3, 3, 5, 'a'},
44 {11723, 3, 3, 3, 'a'},
45 {11403, 3, 3, 2, ' '},
46 {11159, 3, 3, 0, 'a'},
47 {10505, 3, 2, 2, 'a'},
48 {8606, 2, 4, 3, ' '},
49 {6005, 1, 12, 2, ' '},
50 {5875, 1, 12, 1, ' '},
51 {0, 0, 0, 0, ' '} // terminator
54 RealmBuildInfo const* FindBuildInfo(uint16 _build)
56 // first build is low bound of always accepted range
57 if (_build >= ExpectedRealmdClientBuilds[0].build)
58 return &ExpectedRealmdClientBuilds[0];
60 // continue from 1 with explicit equal check
61 for (int i = 1; ExpectedRealmdClientBuilds[i].build; ++i)
62 if (_build == ExpectedRealmdClientBuilds[i].build)
63 return &ExpectedRealmdClientBuilds[i];
65 // none appropriate build
66 return NULL;
69 RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
73 RealmList& sRealmList
75 static RealmList realmlist;
76 return realmlist;
79 /// Load the realm list from the database
80 void RealmList::Initialize(uint32 updateInterval)
82 m_UpdateInterval = updateInterval;
84 ///- Get the content of the realmlist table in the database
85 UpdateRealms(true);
88 void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, RealmFlags realmflags, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, const std::string& builds)
90 ///- Create new if not exist or update existed
91 Realm& realm = m_realms[name];
93 realm.m_ID = ID;
94 realm.icon = icon;
95 realm.realmflags = realmflags;
96 realm.timezone = timezone;
97 realm.allowedSecurityLevel = allowedSecurityLevel;
98 realm.populationLevel = popu;
100 Tokens tokens = StrSplit(builds, " ");
101 Tokens::iterator iter;
103 for (iter = tokens.begin(); iter != tokens.end(); ++iter)
105 uint32 build = atol((*iter).c_str());
106 realm.realmbuilds.insert(build);
109 uint16 first_build = !realm.realmbuilds.empty() ? *realm.realmbuilds.begin() : 0;
111 realm.realmBuildInfo.build = first_build;
112 realm.realmBuildInfo.major_version = 0;
113 realm.realmBuildInfo.minor_version = 0;
114 realm.realmBuildInfo.bugfix_version = 0;
115 realm.realmBuildInfo.hotfix_version = ' ';
117 if (first_build)
118 if (RealmBuildInfo const* bInfo = FindBuildInfo(first_build))
119 if (bInfo->build == first_build)
120 realm.realmBuildInfo = *bInfo;
122 ///- Append port to IP address.
123 std::ostringstream ss;
124 ss << address << ":" << port;
125 realm.address = ss.str();
128 void RealmList::UpdateIfNeed()
130 // maybe disabled or updated recently
131 if (!m_UpdateInterval || m_NextUpdateTime > time(NULL))
132 return;
134 m_NextUpdateTime = time(NULL) + m_UpdateInterval;
136 // Clears Realm list
137 m_realms.clear();
139 // Get the content of the realmlist table in the database
140 UpdateRealms(false);
143 void RealmList::UpdateRealms(bool init)
145 DETAIL_LOG("Updating Realm List...");
147 //// 0 1 2 3 4 5 6 7 8 9
148 QueryResult* result = LoginDatabase.Query("SELECT id, name, address, port, icon, realmflags, timezone, allowedSecurityLevel, population, realmbuilds FROM realmlist WHERE (realmflags & 1) = 0 ORDER BY name");
150 ///- Circle through results and add them to the realm map
151 if (result)
155 Field* fields = result->Fetch();
157 uint32 Id = fields[0].GetUInt32();
158 std::string name = fields[1].GetCppString();
159 uint8 realmflags = fields[5].GetUInt8();
160 uint8 allowedSecurityLevel = fields[7].GetUInt8();
162 if (realmflags & ~(REALM_FLAG_OFFLINE | REALM_FLAG_NEW_PLAYERS | REALM_FLAG_RECOMMENDED | REALM_FLAG_SPECIFYBUILD))
164 sLog.outError("Realm (id %u, name '%s') can only be flagged as OFFLINE (mask 0x02), NEWPLAYERS (mask 0x20), RECOMMENDED (mask 0x40), or SPECIFICBUILD (mask 0x04) in DB", Id, name.c_str());
165 realmflags &= (REALM_FLAG_OFFLINE | REALM_FLAG_NEW_PLAYERS | REALM_FLAG_RECOMMENDED | REALM_FLAG_SPECIFYBUILD);
168 UpdateRealm(
169 Id, name, fields[2].GetCppString(), fields[3].GetUInt32(),
170 fields[4].GetUInt8(), RealmFlags(realmflags), fields[6].GetUInt8(),
171 (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR),
172 fields[8].GetFloat(), fields[9].GetCppString());
174 if (init)
175 sLog.outString("Added realm id %u, name '%s'", Id, name.c_str());
177 while (result->NextRow());
178 delete result;