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
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'},
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
69 RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL
))
75 static RealmList 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
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
];
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
= ' ';
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
))
134 m_NextUpdateTime
= time(NULL
) + m_UpdateInterval
;
139 // Get the content of the realmlist table in the database
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
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
);
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());
175 sLog
.outString("Added realm id %u, name '%s'", Id
, name
.c_str());
177 while (result
->NextRow());