WoW Model Viewer
Your premiere tool for viewing, equipping and animating World of Warcraft models.
Loading...
Searching...
No Matches
WowheadImporter.cpp
Go to the documentation of this file.
1/*----------------------------------------------------------------------*\
2| This file is part of WoW Model Viewer |
3| |
4| WoW Model Viewer is free software: you can redistribute it and/or |
5| modify it under the terms of the GNU General Public License as |
6| published by the Free Software Foundation, either version 3 of the |
7| License, or (at your option) any later version. |
8| |
9| WoW Model Viewer 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. |
13| |
14| You should have received a copy of the GNU General Public License |
15| along with WoW Model Viewer. |
16| If not, see <http://www.gnu.org/licenses/>. |
17\*----------------------------------------------------------------------*/
18
19/*
20 * WowheadImporter.cpp
21 *
22 * Created on: 1 dec. 2013
23 * Copyright: 2013 , WoW Model Viewer (http://wowmodelviewer.net)
24 */
25
26#include "WowheadImporter.h"
27
28#include <algorithm>
29#include <nlohmann/json.hpp>
30
31#include "HttpClient.h"
32#include "database.h" // ItemRecord
33#include "NPCInfos.h"
34#include "Logger.h"
35
37
38bool WowheadImporter::acceptURL(const std::string& url) const
39{
40 return (url.find("wowhead") != std::string::npos);
41}
42
43NPCInfos* WowheadImporter::importNPC(const std::string& urlToGrab) const
44{
45 // Get the HTML...
46 std::string htmldata = getURLData(urlToGrab);
47 if (htmldata.empty())
48 return nullptr;
49
50 // let's go : finding name
51 // extract global infos
52 std::string infos = extractSubString(htmldata, "(g_npcs[", ";");
53
54 // finding name
55 const std::string NPCName = extractSubString(infos, "name\":\"", "\",");
56
57 // finding type
58 const int NPCType = std::stoi(extractSubString(infos, "type\":", "}"));
59
60 // finding id
61 const int NPCId = std::stoi(extractSubString(infos, "id\":", ","));
62
63 // display id
64 std::string NPCDispIdstr = extractSubString(htmldata, "ModelViewer.show({");
65 NPCDispIdstr = extractSubString(NPCDispIdstr, "displayId&quot;:", "}");
66
67 auto commaPos = NPCDispIdstr.find(',');
68 if (commaPos != std::string::npos) // comma at end of id
69 NPCDispIdstr = NPCDispIdstr.substr(0, commaPos);
70
71 const int NPCDispId = std::stoi(NPCDispIdstr);
72
73 NPCInfos* result = new NPCInfos();
74
75 result->name = std::wstring(NPCName.begin(), NPCName.end());
76 result->type = NPCType;
77 result->id = NPCId;
78 result->displayId = NPCDispId;
79
80 return result;
81}
82
83ItemRecord* WowheadImporter::importItem(const std::string& urlToGrab) const
84{
85 ItemRecord* result = nullptr;
86
87 // Get the HTML...
88 std::string htmldata = getURLData(urlToGrab);
89 if (htmldata.empty())
90 return nullptr;
91
92 // let's go : finding name
93 // extract global infos
94 std::string data = extractSubString(htmldata, "(g_items[", ";");
95 data = extractSubString(data, "],");
96 if (!data.empty() && data.back() == ')')
97 data.pop_back();
98
99 const auto infos = nlohmann::json::parse(data, nullptr, false);
100
101 if (infos.is_discarded())
102 {
103 LOG_INFO << "JSON parse error";
104 }
105
106 if (!infos.is_discarded() && infos.size() != 0)
107 {
108 result = new ItemRecord();
109
110 result->name = infos["name"].get<std::string>();
111 result->type = infos["slot"].get<int>();
112 result->id = infos["id"].get<int>();
113 result->model = infos["displayid"].get<int>();
114 result->itemclass = infos["classs"].get<int>();
115 result->subclass = infos["subclass"].get<int>();
116 }
117
118 return result;
119}
120
121std::string WowheadImporter::extractSubString(const std::string& datas, const std::string& beginPattern, const std::string& endPattern) const
122{
123 // Case-insensitive find helper
124 auto findCI = [](const std::string& haystack, const std::string& needle, size_t pos) -> size_t {
125 auto it = std::search(haystack.begin() + pos, haystack.end(),
126 needle.begin(), needle.end(),
127 [](char a, char b) { return std::tolower(static_cast<unsigned char>(a)) == std::tolower(static_cast<unsigned char>(b)); });
128 return (it == haystack.end()) ? std::string::npos : static_cast<size_t>(it - haystack.begin());
129 };
130
131 size_t beginIdx = findCI(datas, beginPattern, 0);
132 if (beginIdx == std::string::npos)
133 return {};
134
135 beginIdx += beginPattern.size();
136 std::string result = datas.substr(beginIdx);
137
138 if (!endPattern.empty())
139 {
140 size_t endIdx = findCI(result, endPattern, 0);
141 if (endIdx != std::string::npos)
142 result = result.substr(0, endIdx);
143 }
144 return result;
145}
146
147std::string WowheadImporter::getURLData(const std::string& inputUrl) const
148{
149 const auto resp = HttpClient::Get(inputUrl);
150 if (!resp.success)
151 {
152 LOG_ERROR << "HTTP request failed: " << resp.error;
153 return {};
154 }
155 return resp.body;
156}
#define LOG_ERROR
Definition Logger.h:11
#define LOG_INFO
Definition Logger.h:10
Stores basic NPC metadata (id, display id, type, name) imported from external sources.
Definition NPCInfos.h:7
int type
NPC type.
Definition NPCInfos.h:16
int id
NPC identifier.
Definition NPCInfos.h:14
int displayId
Creature display info ID.
Definition NPCInfos.h:15
std::wstring name
Display name (wide string).
Definition NPCInfos.h:17
std::string getURLData(const std::string &inputUrl) const
std::string extractSubString(const std::string &datas, const std::string &beginPattern, const std::string &endPattern={}) const
bool acceptURL(const std::string &url) const
ItemRecord * importItem(const std::string &url) const
NPCInfos * importNPC(const std::string &url) const
Response Get(const std::string &url, const ProgressCallback &progress=nullptr)
Perform a synchronous HTTP(S) GET request.
A single equipment item record from the item database.
Definition database.h:26
int itemclass
Definition database.h:28
int model
Definition database.h:28
std::string name
Display name of the item.
Definition database.h:27
int subclass
Definition database.h:28