1 #include <iostream>
2 
3 #include "util/helpers.h"
4 #include "xml.h"
5 #include "evetime.h"
6 #include "apiskillqueue.h"
7 
8 void
set_api_data(EveApiData const & data)9 ApiSkillQueue::set_api_data (EveApiData const& data)
10 {
11   this->valid = false;
12   this->queue.clear();
13 
14   this->ApiBase::set_api_data(data);
15   this->parse_xml();
16 
17   /* Force the skill queue to have a minimum cache time. */
18   this->enforce_cache_time(API_SKILL_QUEUE_MIN_CACHE_TIME);
19 
20 #if 0
21     /* Test skill queue. */
22     ApiSkillQueueItem item;
23     item.queue_pos = 1;
24     item.skill_id = 3323;
25     item.to_level = 3;
26     item.start_sp = 16000;
27     item.end_sp = 16500;
28     item.start_time = "2011-11-05 20:00:00";
29     item.start_time_t = EveTime::get_time_for_string(item.start_time);
30     item.end_time = "2011-11-05 20:00:30";
31     item.end_time_t = EveTime::get_time_for_string(item.end_time);
32 
33     this->queue.clear();
34     this->queue.push_back(item);
35 
36     item.queue_pos = 2;
37     item.skill_id = 3323;
38     item.to_level = 4;
39     item.start_sp = 16500;
40     item.end_sp = 17000;
41     item.start_time = "2011-11-05 20:00:30";
42     item.start_time_t = EveTime::get_time_for_string(item.start_time);
43     item.end_time = "2011-11-05 20:00:59";
44     item.end_time_t = EveTime::get_time_for_string(item.end_time);
45 
46     this->queue.push_back(item);
47 #endif
48 
49   this->valid = true;
50 }
51 
52 /* ---------------------------------------------------------------- */
53 
54 void
parse_xml(void)55 ApiSkillQueue::parse_xml (void)
56 {
57   std::cout << "Parsing XML: SkillQueue.xml ..." << std::endl;
58   XmlDocumentPtr xml = XmlDocument::create
59       (&this->http_data->data[0], this->http_data->data.size());
60   xmlNodePtr root = xml->get_root_element();
61   this->parse_eveapi_tag(root);
62 }
63 
64 /* ---------------------------------------------------------------- */
65 
66 void
parse_eveapi_tag(xmlNodePtr node)67 ApiSkillQueue::parse_eveapi_tag (xmlNodePtr node)
68 {
69   if (node->type != XML_ELEMENT_NODE
70       || xmlStrcmp(node->name, (xmlChar const*)"eveapi"))
71     throw Exception("Invalid XML root. Expecting <eveapi> node.");
72 
73   for (node = node->children; node != 0; node = node->next)
74   {
75     if (node->type != XML_ELEMENT_NODE)
76       continue;
77 
78     /* Let the base class know of some fields. */
79     this->check_node(node);
80 
81     if (!xmlStrcmp(node->name, (xmlChar const*)"result"))
82     {
83       //std::cout << "Found <result> tag" << std::endl;
84       this->parse_result_tag(node->children);
85     }
86   }
87 }
88 
89 /* ---------------------------------------------------------------- */
90 
91 void
parse_result_tag(xmlNodePtr node)92 ApiSkillQueue::parse_result_tag (xmlNodePtr node)
93 {
94   for (; node != 0; node = node->next)
95   {
96     if (node->type != XML_ELEMENT_NODE)
97       continue;
98 
99     if (!xmlStrcmp(node->name, (xmlChar const*)"rowset"))
100     {
101       std::string name = this->get_property(node, "name");
102       if (name == "skillqueue")
103         this->parse_queue_rowset(node->children);
104     }
105   }
106 }
107 
108 /* ---------------------------------------------------------------- */
109 
110 void
parse_queue_rowset(xmlNodePtr node)111 ApiSkillQueue::parse_queue_rowset (xmlNodePtr node)
112 {
113   for (; node != 0; node = node->next)
114   {
115     if (node->type != XML_ELEMENT_NODE)
116       continue;
117 
118     if (!xmlStrcmp(node->name, (xmlChar const*)"row"))
119     {
120       std::string pos = this->get_property(node, "queuePosition");
121       std::string type_id = this->get_property(node, "typeID");
122       std::string level = this->get_property(node, "level");
123       std::string startsp = this->get_property(node, "startSP");
124       std::string endsp = this->get_property(node, "endSP");
125 
126       ApiSkillQueueItem item;
127       item.start_time = this->get_property(node, "startTime");
128       item.end_time = this->get_property(node, "endTime");
129       item.queue_pos = Helpers::get_int_from_string(pos);
130       item.skill_id = Helpers::get_int_from_string(type_id);
131       item.to_level = Helpers::get_int_from_string(level);
132       item.start_sp = Helpers::get_int_from_string(startsp);
133       item.end_sp = Helpers::get_int_from_string(endsp);
134       /* Paused queue results in empty start/end-time. This yields -1 here. */
135       item.start_time_t = EveTime::get_time_for_string(item.start_time);
136       item.end_time_t = EveTime::get_time_for_string(item.end_time);
137 
138       this->queue.push_back(item);
139     }
140   }
141 
142   //this->debug_dump();
143 }
144 
145 /* ---------------------------------------------------------------- */
146 
147 bool
in_training(void) const148 ApiSkillQueue::in_training (void) const
149 {
150     if (this->queue.empty())
151         return false;
152     /* If end time of last skill lies in the past, or is -1 (paused),
153      * we return false and indicate that no skill is in training. */
154     if (this->queue.back().end_time_t < EveTime::get_eve_time())
155         return false;
156     return true;
157 }
158 
159 /* ---------------------------------------------------------------- */
160 
161 bool
is_paused(void) const162 ApiSkillQueue::is_paused (void) const
163 {
164     if (this->queue.empty())
165         return false;
166     return this->queue.front().end_time_t == -1;
167 }
168 
169 /* ---------------------------------------------------------------- */
170 
171 ApiSkillQueueItem const*
get_training_skill(void) const172 ApiSkillQueue::get_training_skill (void) const
173 {
174     if (this->queue.empty())
175         return 0;
176 
177     time_t eve_time = EveTime::get_eve_time();
178     for (std::size_t i = 0; i < this->queue.size(); ++i)
179         if (this->queue[i].end_time_t >= eve_time)
180             return &this->queue[i];
181 
182     return 0;
183 }
184 
185 /* ---------------------------------------------------------------- */
186 
187 unsigned int
get_spph_for_current(void) const188 ApiSkillQueue::get_spph_for_current (void) const
189 {
190   ApiSkillQueueItem const* item = this->get_training_skill();
191   if (item == 0)
192     return 0;
193 
194   double skill_sp = (double)(item->end_sp - item->start_sp);
195   double train_time = (double)(item->end_time_t - item->start_time_t);
196   return (unsigned int)(skill_sp * 3600.0 / train_time);
197 }
198 
199 /* ---------------------------------------------------------------- */
200 
201 void
debug_dump(void)202 ApiSkillQueue::debug_dump (void)
203 {
204   std::cout << "=== Skill Queue dump ===" << std::endl;
205   for (std::size_t i = 0; i < this->queue.size(); ++i)
206   {
207     ApiSkillQueueItem const& item = this->queue[i];
208     std::cout << "Element " << i << ": Position " << item.queue_pos
209         << ", Skill ID " << item.skill_id << " (" << item.to_level << ")"
210         << ", from " << item.start_sp << " to " << item.end_sp << " SP"
211         << ", from unix time " << item.start_time_t
212         << " to " << item.end_time_t << std::endl;
213   }
214 }
215