ConfigReader.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator 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. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "ConfigReader.h"
  17. #include "Log.h"
  18. ConfigReader::~ConfigReader(){
  19. MStructs.lock();
  20. DestroyStructs();
  21. MStructs.unlock();
  22. }
  23. PacketStruct* ConfigReader::getStructByVersion(const char* name, int16 version){
  24. PacketStruct* packet = 0;
  25. PacketStruct* newpacket = 0;
  26. MStructs.lock();
  27. vector<PacketStruct*>* struct_versions = structs[string(name)];
  28. if(struct_versions){
  29. vector<PacketStruct*>::iterator iter;
  30. for(iter = struct_versions->begin(); iter != struct_versions->end(); iter++){
  31. packet = *iter;
  32. if(packet && packet->GetVersion() == version){
  33. newpacket = new PacketStruct(packet, version);
  34. break;
  35. }
  36. }
  37. }
  38. MStructs.unlock();
  39. if(!newpacket)
  40. LogWrite(PACKET__ERROR, 0, "Packet", "Could not find struct named '%s' with version: %i", name, version);
  41. return newpacket;
  42. }
  43. void ConfigReader::ReloadStructs(){
  44. MStructs.lock();
  45. DestroyStructs();
  46. for(int32 i=0;i<load_files.size();i++)
  47. processXML_Elements(load_files[i].c_str());
  48. MStructs.unlock();
  49. }
  50. void ConfigReader::DestroyStructs(){
  51. map<string, vector<PacketStruct*>*>::iterator struct_iterator;
  52. for(struct_iterator=structs.begin();struct_iterator!=structs.end();struct_iterator++) {
  53. vector<PacketStruct*>* versions = struct_iterator->second;
  54. vector<PacketStruct*>::iterator version_iter;
  55. if(versions){
  56. for(version_iter = versions->begin(); version_iter != versions->end(); version_iter++){
  57. safe_delete(*version_iter);
  58. }
  59. }
  60. safe_delete(versions);
  61. }
  62. structs.clear();
  63. }
  64. PacketStruct* ConfigReader::getStruct(const char* name, int16 version){
  65. PacketStruct* latest_version = 0;
  66. PacketStruct* new_latest_version = 0;
  67. MStructs.lock();
  68. vector<PacketStruct*>* struct_versions = structs[string(name)];
  69. if(struct_versions){
  70. vector<PacketStruct*>::iterator iter;
  71. for(iter = struct_versions->begin(); iter != struct_versions->end(); iter++){
  72. if((*iter)->GetVersion() <= version && (!latest_version || (*iter)->GetVersion() > latest_version->GetVersion()))
  73. latest_version = *iter;
  74. }
  75. if (latest_version) {
  76. if(strlen(latest_version->GetOpcodeType()) == 0 || latest_version->GetOpcode() != OP_Unknown)
  77. new_latest_version = new PacketStruct(latest_version, version);
  78. else {
  79. cout << "here: " << latest_version->GetOpcodeType() << endl;
  80. LogWrite(PACKET__ERROR, 0, "Packet", "Could not find valid opcode for Packet Struct '%s' and client version %d", latest_version->GetOpcodeType(), version);
  81. }
  82. }
  83. }
  84. MStructs.unlock();
  85. if(!new_latest_version)
  86. LogWrite(PACKET__ERROR, 0, "Packet", "Could not find struct named '%s'", name);
  87. return new_latest_version;
  88. }
  89. int16 ConfigReader::GetStructVersion(const char* name, int16 version){
  90. MStructs.lock();
  91. vector<PacketStruct*>* struct_versions = structs[string(name)];
  92. int16 ret = 0;
  93. if(struct_versions){
  94. vector<PacketStruct*>::iterator iter;
  95. PacketStruct* latest_version = 0;
  96. for(iter = struct_versions->begin(); iter != struct_versions->end(); iter++){
  97. if(!latest_version || ( (*iter)->GetVersion() > latest_version->GetVersion() && (*iter)->GetVersion() <= version) )
  98. latest_version = *iter;
  99. }
  100. if(latest_version)
  101. ret = latest_version->GetVersion();
  102. }
  103. MStructs.unlock();
  104. return ret;
  105. }
  106. void ConfigReader::addStruct(const char* name, int16 version, PacketStruct* new_struct){
  107. string strname(name);
  108. vector<PacketStruct*>* struct_versions = structs[strname];
  109. if(struct_versions)
  110. struct_versions->push_back(new_struct);
  111. else{
  112. struct_versions = new vector<PacketStruct*>;
  113. struct_versions->push_back(new_struct);
  114. structs[strname] = struct_versions;
  115. }
  116. }
  117. bool ConfigReader::LoadFile(const char* name){
  118. load_files.push_back(name);
  119. return processXML_Elements(name);
  120. }
  121. bool ConfigReader::processXML_Elements(const char* fileName){
  122. XMLNode xMainNode=XMLNode::openFileHelper(fileName,"EQ2Emulator");
  123. if(xMainNode.isEmpty())
  124. return false;
  125. for(int i=0;i<xMainNode.nChildNode("Struct");i++){
  126. const char* struct_name = xMainNode.getChildNode("Struct", i).getAttribute("Name");
  127. const char* str_version = xMainNode.getChildNode("Struct", i).getAttribute("ClientVersion");
  128. const char* opcode_name = xMainNode.getChildNode("Struct", i).getAttribute("OpcodeName");
  129. const char* opcode_type = xMainNode.getChildNode("Struct", i).getAttribute("OpcodeType");
  130. if(!struct_name || !str_version)
  131. {
  132. LogWrite(MISC__WARNING, 0, "Misc", "Ignoring invalid struct, all structs must include at least a Name and ClientVersion!");
  133. continue;
  134. }
  135. int16 version = 1;
  136. try
  137. {
  138. version = atoi(str_version);
  139. }
  140. catch(...)
  141. {
  142. LogWrite(MISC__WARNING, 0, "Misc", "Ignoring invalid version for struct named '%s': '%s'", struct_name, str_version);
  143. continue;
  144. }
  145. PacketStruct* new_struct = new PacketStruct();
  146. new_struct->SetName(struct_name);
  147. if(opcode_type)
  148. new_struct->SetOpcodeType(opcode_type);
  149. if(opcode_name){
  150. if(!new_struct->SetOpcode(opcode_name)){
  151. safe_delete(new_struct);
  152. continue;
  153. }
  154. }
  155. new_struct->SetVersion(version);
  156. loadDataStruct(new_struct, xMainNode.getChildNode("Struct", i));
  157. addStruct(struct_name, version, new_struct);
  158. }
  159. return true;
  160. }
  161. void ConfigReader::loadDataStruct(PacketStruct* packet, XMLNode parentNode, bool array_packet){
  162. for(int x=0;x<parentNode.nChildNode();x++){
  163. const char* name = parentNode.getChildNode("Data", x).getAttribute("ElementName");
  164. const char* type = parentNode.getChildNode("Data", x).getAttribute("Type");
  165. const char* size = parentNode.getChildNode("Data", x).getAttribute("Size");
  166. const char* type2 = parentNode.getChildNode("Data", x).getAttribute("Type2");
  167. const char* array_size = parentNode.getChildNode("Data", x).getAttribute("ArraySizeVariable");
  168. const char* max_array = parentNode.getChildNode("Data", x).getAttribute("MaxArraySize");
  169. const char* substruct = parentNode.getChildNode("Data", x).getAttribute("Substruct");
  170. const char* default_value = parentNode.getChildNode("Data", x).getAttribute("DefaultByteValue");
  171. const char* oversized = parentNode.getChildNode("Data", x).getAttribute("OversizedValue");
  172. const char* oversized_byte = parentNode.getChildNode("Data", x).getAttribute("OversizedByte");
  173. const char* if_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableSet");
  174. const char* if_not_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableNotSet");
  175. const char* if_equals_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableEquals");
  176. const char* if_not_equals_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableNotEquals");
  177. const char* optional = parentNode.getChildNode("Data", x).getAttribute("Optional");
  178. const char* if_flag_not_set_variable = parentNode.getChildNode("Data", x).getAttribute("IfFlagNotSet");
  179. const char* if_flag_set_variable = parentNode.getChildNode("Data", x).getAttribute("IfFlagSet");
  180. //const char* type2criteria = parentNode.getChildNode("Data", x).getAttribute("Type2Criteria"); // JA: LE added to PacketAnalyzer for Items parsing - 12.2012
  181. //const char* criteria = parentNode.getChildNode("Data", x).getAttribute("Criteria"); // JA: LE added to PacketAnalyzer for Items parsing - 12.2012
  182. int8 max_array_size = 0;
  183. try{
  184. if(max_array)
  185. max_array_size = atoi(max_array);
  186. }
  187. catch(...){}
  188. int16 num_size = 1;
  189. try{
  190. if(size)
  191. num_size = atoi(size);
  192. }
  193. catch(...){}
  194. int8 byte_val = 0;
  195. try{
  196. if(default_value)
  197. byte_val = atoi(default_value);
  198. }
  199. catch(...){}
  200. if(substruct && name){
  201. PacketStruct* substruct_packet = getStruct(substruct, packet->GetVersion());
  202. if(substruct_packet){
  203. vector<DataStruct*>::iterator itr;
  204. vector<DataStruct*>* structs = substruct_packet->getStructs();
  205. DataStruct* ds = 0;
  206. int i = 0;
  207. char tmp[10] = {0};
  208. for(i=0;i<num_size;i++){
  209. sprintf(tmp,"%i",i);
  210. for(itr=structs->begin();itr!=structs->end();itr++) {
  211. ds = *itr;
  212. string new_name;
  213. if(array_packet)
  214. new_name = string(name).append("_").append(ds->GetStringName());
  215. else
  216. new_name = string(name).append("_").append(ds->GetStringName()).append("_").append(tmp);
  217. DataStruct* ds2 = new DataStruct(new_name.c_str(), ds->GetType(),ds->GetLength(), ds->GetType2());
  218. if(!array_packet && strlen(ds->GetArraySizeVariable()) > 1)
  219. ds2->SetArraySizeVariable(string(name).append("_").append(ds->GetArraySizeVariable()).append("_").append(tmp).c_str());
  220. ds2->SetOversized(ds->GetOversized());
  221. ds2->SetOversizedByte(ds->GetOversizedByte());
  222. ds2->SetDefaultValue(ds->GetDefaultValue());
  223. ds2->SetMaxArraySize(ds->GetMaxArraySize());
  224. ds2->SetIfSetVariable(ds->GetIfSetVariable());
  225. ds2->SetIfNotSetVariable(ds->GetIfNotSetVariable());
  226. ds2->SetIfEqualsVariable(ds->GetIfEqualsVariable());
  227. ds2->SetIfNotEqualsVariable(ds->GetIfNotEqualsVariable());
  228. ds2->SetIfFlagNotSetVariable(ds->GetIfFlagNotSetVariable());
  229. ds2->SetIfFlagSetVariable(ds->GetIfFlagSetVariable());
  230. ds2->SetIsOptional(ds->IsOptional());
  231. packet->add(ds2);
  232. }
  233. }
  234. if(!array_packet){
  235. i--;
  236. substruct_packet->renameSubstructArray(name, i);
  237. //ds2->SetArraySizeVariable((char*)string(name).append("_").append(ds->GetArraySizeVariable()).append("_").append(tmp).c_str());
  238. packet->addPacketArrays(substruct_packet);
  239. }
  240. safe_delete(substruct_packet);
  241. }
  242. continue;
  243. }
  244. else if(type && strncasecmp(type,"Array", 5)==0 && array_size){
  245. PacketStruct* new_packet = new PacketStruct;
  246. new_packet->SetName(name);
  247. new_packet->IsSubPacket(true);
  248. new_packet->SetVersion(packet->GetVersion());
  249. loadDataStruct(new_packet, parentNode.getChildNode("Data", x), true);
  250. packet->add(new_packet);
  251. }
  252. if(!name || !type)
  253. {
  254. LogWrite(MISC__WARNING, 0, "Misc", "Ignoring invalid Data Element, all elements must include at least an ElementName and Type!");
  255. LogWrite(MISC__WARNING, 0, "Misc", "\tStruct: '%s', version: %i", parentNode.getAttribute("Name"), parentNode.getAttribute("ClientVersion"));
  256. continue;
  257. }
  258. DataStruct* ds = new DataStruct(name, type, num_size, type2);
  259. int8 oversized_value = 0;
  260. int8 oversized_byte_value = 255;
  261. if(oversized){
  262. try{
  263. oversized_value = atoi(oversized);
  264. }
  265. catch(...){}
  266. }
  267. if(oversized_byte){
  268. try{
  269. oversized_byte_value = atoi(oversized_byte);
  270. }
  271. catch(...){}
  272. }
  273. ds->SetOversizedByte(oversized_byte_value);
  274. ds->SetOversized(oversized_value);
  275. ds->SetMaxArraySize(max_array_size);
  276. if(array_size)
  277. ds->SetArraySizeVariable(array_size);
  278. ds->SetDefaultValue(byte_val);
  279. ds->SetIfSetVariable(if_variable);
  280. ds->SetIfNotSetVariable(if_not_variable);
  281. ds->SetIfEqualsVariable(if_equals_variable);
  282. ds->SetIfNotEqualsVariable(if_not_equals_variable);
  283. ds->SetIfFlagNotSetVariable(if_flag_not_set_variable);
  284. ds->SetIfFlagSetVariable(if_flag_set_variable);
  285. if (optional && strlen(optional) > 0 && (strcmp("true", optional) == 0 || strcmp("TRUE", optional) == 0 || strcmp("True", optional) == 0))
  286. ds->SetIsOptional(true);
  287. packet->add(ds);
  288. }
  289. }