static T_Status Append_Extension(T_Glyph_Ptr filename, T_File_Attribute attributes, T_Void_Ptr context) { long result; bool is_partial; T_Glyph_Ptr base_filename, output_folder = (T_Glyph_Ptr) context; T_XML_Node root; T_XML_Document document; T_Filename output_filename; if ((attributes & e_filetype_directory) != 0) x_Status_Return_Success(); /* Read the file in from the temporary folder as an XML document */ result = XML_Read_Document(&document, &l_data, filename); if (x_Trap_Opt(result != 0)) { Log_Message("Could not read XML document."); x_Status_Return_Success(); } /* Get the base filename to use for this file */ base_filename = strrchr(filename, DIR[0]); if (x_Trap_Opt(base_filename == NULL)) x_Status_Return(LWD_ERROR); base_filename++; if (x_Trap_Opt(*base_filename == '\0')) x_Status_Return(LWD_ERROR); /* Query and unset the artificial "partial" flag we added, so it doesn't confuse things by showing up in the real data file we're about to output. */ result = XML_Get_Document_Node(document, &root); if (x_Trap_Opt(result != 0)) x_Status_Return_Success(); is_partial = XML_Read_Boolean_Attribute(root, "ispartial"); XML_Write_Boolean_Attribute(root, "ispartial", false); /* Append any extensions to the document */ Append_Extensions(document, output_folder, base_filename, is_partial); /* Back up any existing file and write out the new one */ sprintf(output_filename, "%s" DIR "%s", output_folder, base_filename); Backup_Existing(output_filename); result = XML_Write_Document(document, output_filename, false, true); if (x_Trap_Opt(result != 0)) { Log_Message("Could not write XML document."); x_Status_Return_Success(); } XML_Destroy_Document(document); x_Status_Return_Success(); }
static T_Status Login(T_WWW internet, T_Glyph_Ptr email, T_Glyph_Ptr password, bool is_report_success) { static T_Glyph_Ptr l_last_email = NULL; static T_Glyph_Ptr l_last_password = NULL; T_Status status; T_Glyph_Ptr ptr, newline, invalid; /* Save our last email and password if given, or re-use them if we weren't passed in an email or password */ if (email != NULL) l_last_email = email; else email = l_last_email; if (password != NULL) l_last_password = password; else password = l_last_password; /* If we don't have an email or password, we can't log in */ if ((email[0] == '\0') || (password[0] == '\0')) x_Status_Return_Success(); /* Set up our arrays of name/value parameters to use for the login POST */ T_Glyph_Ptr names[] = { "email", "password" }; T_Glyph_Ptr values[] = { email, password }; /* Logging in is a simple POST of our username & password to the D&DI server */ status = WWW_HTTP_Post(internet,LOGIN_URL,x_Array_Size(names),names,values,&ptr); if (x_Trap_Opt(!x_Is_Success(status))) { Log_Message("Couldn't make login HTTP post!\n", true); x_Status_Return(status); } /* If the string 'invalid' appears in the first line of our response, it's a failed login. */ newline = strchr(ptr, '\n'); if (newline == NULL) { Log_Message("\n**** Login error - could not log in to D&D insider.\n", true); x_Status_Return(LWD_ERROR); } invalid = strstr(ptr, "invalid"); if ((invalid != NULL) && (invalid < newline)) { Log_Message("\n**** Login error - username / password not recognised.\n", true); x_Status_Return(LWD_ERROR); } Log_Message("Login succeeded.\n", is_report_success); l_is_password = true; x_Status_Return_Success(); }
T_Status C_DDI_Rituals::Parse_Index_Cell(T_XML_Node node, T_Ritual_Info * info, T_Int32U subtype) { T_Status status; status = Get_Required_Child_PCDATA(&info->level, node, "Level"); if (!x_Is_Success(status)) x_Status_Return(status); status = Get_Required_Child_PCDATA(&info->price, node, "Price"); if (!x_Is_Success(status)) x_Status_Return(status); /* If our level is '0', that's obviously nonsense so get rid of it */ if ((info->level[0] == '0') && (info->level[1] == '\0')) info->level = ""; status = Get_Required_Child_PCDATA(&info->componentcost, node, "ComponentCost"); if (!x_Is_Success(status)) x_Status_Return(status); status = Get_Required_Child_PCDATA(&info->keyskill, node, "KeySkillDescription"); if (!x_Is_Success(status)) x_Status_Return(status); x_Status_Return_Success(); }
T_Status C_DDI_Rituals::Post_Process_Entry(T_XML_Node root, T_Ritual_Info * info) { /* Now that our feats all have unique ids, output our prereqs - we need to add identity tags for feats that may not have been processed yet, so this must be done in the Post_Process stage */ Output_Prereqs(info, &m_id_list); x_Status_Return_Success(); }
T_Status C_DDI_Deities::Parse_Index_Cell(T_XML_Node node, T_Deity_Info * info, T_Int32U subtype) { T_Status status; status = Get_Required_Child_PCDATA(&info->alignment, node, "Alignment"); if (!x_Is_Success(status)) x_Status_Return(status); x_Status_Return_Success(); }
T_Status C_DDI_Backgrounds::Post_Process_Entry(T_XML_Node root, T_Background_Info * info) { /* Now that our feats all have unique ids, output our prereqs - we need to add identity tags for feats that may not have been processed yet, so this must be done in the Post_Process stage */ Output_Prereqs(info, &m_id_list); /* Generate scripts / tags / fields / etc for everything */ Generate_Mechanics(info, &m_id_list, m_pool); x_Status_Return_Success(); }
/* Note - this function should be resilient to stuff in the HTML changing, so if we don't find what we expect, we should just return successfully and not complain about it. */ T_Status C_DDI_Deities::Parse_Entry_Details(T_Glyph_Ptr contents, T_Deity_Info * info, T_Glyph_Ptr ptr, T_Glyph_Ptr checkpoint, vector<T_Deity_Info> * extras) { T_Status status; T_Glyph_Ptr end; ptr = Extract_Text(&info->flavor, m_pool, ptr, checkpoint, "<b>Type: </b>", "<br"); ptr = Extract_Text(&info->alignment, m_pool, ptr, checkpoint, "<b>Alignment :</b>", "</b><br"); ptr = Extract_Text(&info->gender, m_pool, ptr, checkpoint, "<b>Gender:</b>", "<br"); ptr = Extract_Text(&info->sphere, m_pool, ptr, checkpoint, "<b>Sphere:</b>", "<br"); ptr = Extract_Text(&info->dominion, m_pool, ptr, checkpoint, "<b>Dominion:</b>", "<br"); ptr = Extract_Text(&info->priests, m_pool, ptr, checkpoint, "<b>Priests:</b>", "<br"); ptr = Extract_Text(&info->adjective, m_pool, ptr, checkpoint, "<b>Adjective:</b>", "<br"); /* The description text appears after the end of the paragraph node */ ptr = Find_Text(ptr, "</p>", checkpoint, true, false); if (x_Trap_Opt(ptr == NULL)) x_Status_Return_Success(); end = Find_Text(ptr, "<p>", checkpoint, false, false); if (x_Trap_Opt(end == NULL)) x_Status_Return_Success(); *end = '\0'; status = Parse_Description_Text(&info->description, ptr, m_pool); if (x_Trap_Opt(!x_Is_Success(status))) x_Status_Return(status); *end = '<'; x_Status_Return_Success(); }
static T_Status Finish_Document(T_XML_Document document, T_Glyph_Ptr output_folder, T_Glyph_Ptr filename) { T_Int32S result; T_Glyph buffer[MAX_FILE_NAME+1]; sprintf(buffer, "%s" DIR "%s", output_folder, filename); Backup_Existing(buffer); /* Output the document into our output folder */ result = XML_Write_Document(document, buffer, false, true); if (x_Trap_Opt(result != 0)) { sprintf(buffer, "Could not write %s XML document.", filename); Log_Message(buffer); x_Status_Return(LWD_ERROR); } x_Status_Return_Success(); }
static T_Status Create_Document(T_XML_Document * document, T_XML_Node * root, T_Glyph_Ptr name, T_XML_Element * element) { T_Int32S result; T_Glyph buffer[500]; result = XML_Create_Document(document, element, false); if (x_Trap_Opt(result != 0)) { sprintf(buffer, "Could not create %s XML document.", name); Log_Message(buffer); x_Status_Return(LWD_ERROR); } result = XML_Get_Document_Node(*document, root); if (x_Trap_Opt(result != 0)) { sprintf(buffer, "Could not get %s XML document root.", name); Log_Message(buffer); x_Status_Return(LWD_ERROR); } x_Status_Return_Success(); }
/* Note - this function should be resilient to stuff in the HTML changing, so if we don't find what we expect, we should just return successfully and not complain about it. */ T_Status C_DDI_Rituals::Parse_Entry_Details(T_Glyph_Ptr contents, T_Ritual_Info * info, T_Glyph_Ptr ptr, T_Glyph_Ptr checkpoint, vector<T_Ritual_Info> * extras) { T_Status status; T_Glyph_Ptr end; T_Glyph_Ptr starts[] = { "???", }; T_Glyph_Ptr ends[] = { "<br", "</p", "</span" }; ptr = Extract_Text(&info->flavor, m_pool, ptr, checkpoint, "<span class=\"flavor\">", "</span>"); Strip_Bad_Characters(info->flavor); /* This was parsed from the index above, but we might as well grab it again here, in case there's more information */ starts[0] = "<b>Component Cost</b>:"; ptr = Extract_Text(&info->componentcost, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->componentcost); /* Although we've parsed the skill out of the index, replace it if we can - the one on the actual page has more data (e.g. "no check" info). */ starts[0] = "<b>Key Skill</b>:"; ptr = Extract_Text(&info->keyskill, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->keyskill); /* Although we've parsed the level out of the index, replace it if we can - the one on the actual page has more data. */ starts[0] = "<b>Level</b>:"; ptr = Extract_Text(&info->level, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->level); starts[0] = "<b>Category</b>:"; ptr = Extract_Text(&info->category, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->category); starts[0] = "<b>Time</b>:"; ptr = Extract_Text(&info->time, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->time); starts[0] = "<b>Duration</b>:"; ptr = Extract_Text(&info->duration, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->duration); starts[0] = "<b>Prerequisite</b>:"; ptr = Extract_Text(&info->prerequisite, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->prerequisite); /* Parse out any paragraph close tag we encounter here */ if (strnicmp(ptr, "</p>", 4) == 0) ptr += 4; /* Now parse the rest of the description - it might end in a </p> tag, or it might not! Who knows! */ end = Find_Text(ptr, "</p>", checkpoint, false, false); if (end == NULL) end = checkpoint; *end = '\0'; status = Parse_Description_Text(&info->description, ptr, m_pool); if (x_Trap_Opt(!x_Is_Success(status))) x_Status_Return(status); *end = '<'; x_Status_Return_Success(); }
T_Status C_DDI_Monsters::Post_Process_Entry(T_XML_Node root, T_Monster_Info * info) { x_Status_Return_Success(); }
T_Status C_DDI_Skills::Post_Process_Entry(T_XML_Node root, T_Skill_Info * info) { x_Status_Return_Success(); }
static T_Status Restore_Old_File(T_Glyph_Ptr filename, T_File_Attribute attributes, T_Void_Ptr context) { T_Status status; T_Glyph_Ptr base_filename, output_folder = (T_Glyph_Ptr) context; T_Filename file_old, file_new, file_temp; T_Glyph buffer[1000]; if ((attributes & e_filetype_directory) != 0) x_Status_Return_Success(); /* Get the base filename to use for this file */ base_filename = strrchr(filename, DIR[0]); if (x_Trap_Opt(base_filename == NULL)) x_Status_Return(LWD_ERROR); base_filename++; if (x_Trap_Opt(*base_filename == '\0')) x_Status_Return(LWD_ERROR); /* Get the temporary filename we'll use for stuff */ sprintf(file_temp, "%s" DIR "temporary.ignore", output_folder); /* Get filenames for our source, and target files. The source is the one we just found; the target is that with ".saved" chopped off the end. */ sprintf(file_old, "%s" DIR "%s", output_folder, base_filename); strcpy(file_new, file_old); file_new[strlen(file_new) - strlen(BACKUP_EXTENSION)] = '\0'; sprintf(buffer, "Restoring %s...\n", base_filename); Log_Message(buffer, true); /* We want to swap the two files, so that the new is replaced by the old. */ FileSys_Delete_File(file_temp, FALSE); if (FileSys_Does_File_Exist(file_new)) { status = FileSys_Copy_File(file_temp, file_new, FALSE); if (!x_Is_Success(status)) { sprintf(buffer, "Couldn't make a backup of %s!\n", file_new); Log_Message(buffer, true); } } if (FileSys_Does_File_Exist(file_old)) { status = FileSys_Copy_File(file_new, file_old, FALSE); if (!x_Is_Success(status)) { sprintf(buffer, "Couldn't restore old file %s!\n", file_old); Log_Message(buffer, true); } } if (FileSys_Does_File_Exist(file_temp)) { status = FileSys_Copy_File(file_old, file_temp, FALSE); if (!x_Is_Success(status)) { sprintf(buffer, "Couldn't restore backup of new file %s!\n", file_new); Log_Message(buffer, true); } } FileSys_Delete_File(file_temp, FALSE); x_Status_Return_Success(); }