/** * This is a general newspaper edition handler. It will deal with keeping * track of all the data for all the newspapers on the mud. * @author Pinkfish * @started Sat Apr 28 02:30:49 PDT 2001 */ #include <room/newspaper.h> #include <nroff.h> #include <autodoc.h> #include <login_handler.h> #define SAVE_DIR "/save/newspaper/" class edition { int date_published; class article* articles; class advert* adverts; string headline; int num_sold; int num_web_hits; int total_revenue; } class paper { class edition* published_editions; string dir_name; string long; string description; string office; int paper_cost; string language; } private mapping _papers; private mapping _areas; private mapping _xp; private mapping _inform; void load_me(); void save_me(); void create() { _papers = ([ ]); _areas = ([ ]); _xp = ([ ]); _inform = ([ ]); seteuid(getuid()); load_me(); if (!_inform) { _inform = ([ ]); } } /* create() */ /** * This method checks to see if the paper exists. * @param paper the paper name to check for */ int is_paper(string paper) { return classp(_papers[paper]); } /* is_paper() */ /** * This method adds a paper. * @param paper the name of the paper * @param long the description on the newspapers themselves * @param desc the description on the web page * @param office the path to the office */ void add_paper(string name, string long, string desc, string office, string language) { if (is_paper(name)) { return ; } _papers[name] = new(class paper); _papers[name]->published_editions = ({ }); _papers[name]->dir_name = replace_string(lower_case(name), " ", "_"); _papers[name]->long = long; _papers[name]->description = desc; _papers[name]->office = office; _papers[name]->paper_cost = 5 * 4; _papers[name]->language = language; save_me(); } /* add_paper() */ /** * This method returns the list of all the papers. * @return all the papers */ string* query_all_papers() { return keys(_papers); } /* query_all_papers() */ /** * This method returns the current edition of the paper. * @param paper the paper to get the edition of * @return the current edition */ int query_current_edition_num(string paper) { if (!is_paper(paper)) { return 0; } return sizeof(_papers[paper]->published_editions) + 1; } /* query_current_edition_num() */ /** * This method returns the last edition of the paper. * @param paper the paper to get the edition of * @return the last edition, 0 if there are no editions */ int query_last_edition_num(string paper) { if (!is_paper(paper)) { return 0; } return sizeof(_papers[paper]->published_editions); } /* query_last_edition_num() */ /** * This checks to see if the specified edition is valid or not. * @param paper the paper to check * @param edition the edition to check * @return 1 if it ok, 0 if not */ int is_valid_edition(string paper, int edition) { if (!is_paper(paper)) { return 0; } if (edition > 0 && edition <= sizeof(_papers[paper]->published_editions)) { return 1; } return 0; } /* is_valid_edition() */ /** * This method returns the date at which the specified issue was * published. * @param paper the paper to check * @param edition the edition to look up * @return the date at which the edition was published */ int query_edition_date(string paper, int edition) { if (!is_paper(paper)) { return 0; } if (!is_valid_edition(paper, edition)) { return 0; } return _papers[paper]->published_editions[edition - 1]->date_published; } /* query_edition_date() */ /** * This method returns the articles in the specified edition of the * paper. * @param paper the paper to look up * @param edition the edition to look up * @return the articles in the edition */ class article* query_edition_articles(string paper, int edition) { if (!is_paper(paper)) { return ({ }); } if (!is_valid_edition(paper, edition)) { return ({ }); } return copy(_papers[paper]->published_editions[edition - 1]->articles); } /* query_edition_articles() */ /** * This method returns the adverts in the specified edition of the * paper. * @param paper the paper to look up * @param edition the edition to look up * @return the adverts in the edition */ class advert* query_edition_adverts(string paper, int edition) { if (!is_paper(paper)) { return ({ }); } if (!is_valid_edition(paper, edition)) { return ({ }); } return copy(_papers[paper]->published_editions[edition - 1]->adverts); } /* query_edition_adverts() */ /** * This method returns the office of the paper. * @param paper the paper to look up * @return the office of the paper */ string query_paper_office(string paper) { if (!is_paper(paper)) { return 0; } return _papers[paper]->office; } /* query_paper_headline() */ /** * This method sets the office of the paper. * @param paper the paper to look up * @param office the new office of the paper */ void set_paper_office(string paper, string office) { if (!is_paper(paper)) { return 0; } _papers[paper]->office = office; save_me(); } /* query_paper_headline() */ /** * This method returns the headline for the selected edition of the paper. * @param paper the paper to look up * @param edition the edition to look up * @return the headline of the edition */ string query_paper_headline(string paper, int edition) { if (!is_valid_edition(paper, edition)) { return "No news is good news."; } return _papers[paper]->published_editions[edition - 1]->headline; } /* query_paper_headline() */ /** * This method returns the headline for the selected edition of the paper. * @param paper the paper to look up * @param edition the edition to look up * @param headline the headline of the issue */ void set_paper_headline(string paper, int edition, string headline) { if (!is_valid_edition(paper, edition)) { return ; } _papers[paper]->published_editions[edition - 1]->headline = headline; save_me(); } /* set_paper_headline() */ /** * This method returns the total revenue for this edition. * @param paper the paper to look up * @param edition the edition to look up * @return the headline of the edition */ int query_edition_revenue(string paper, int edition) { if (!is_valid_edition(paper, edition)) { return 0; } return _papers[paper]->published_editions[edition - 1]->total_revenue; } /* query_edition_revenue() */ /** * This method adds to the total revenue for this edition. * @param paper the paper to look up * @param edition the edition to look up * @param revenue the revenue to add */ void add_edition_revenue(string paper, int edition, int revenue) { if (!is_valid_edition(paper, edition)) { return ; } _papers[paper]->published_editions[edition - 1]->total_revenue += revenue; save_me(); } /* add_edition_headline() */ /** * This method adds a web hit to the specified edition. * @param paper the paper to add a hit on * @param edition the edition to add a hit on */ void add_edition_web_hit(string paper, int edition) { if (!is_valid_edition(paper, edition)) { return ; } _papers[paper]->published_editions[edition - 1]->num_web_hits++; _papers[paper]->published_editions[edition - 1]->total_revenue += NEWSPAPER_WEB_HIT_REVENUE; save_me(); } /* add_edition_web_hit() */ /** * This method adds a web paper sold to the specified edition. * @param paper the paper which was sold * @param edition the edition which was sold * @param cost the amount it was sold for */ void add_edition_paper_sold(string paper, int edition, int cost) { if (!is_valid_edition(paper, edition)) { tell_creator("pinkfish", "Not valid edition %O %O\n", paper, previous_object()); return ; } tell_creator("pinkfish", "Updating num sold %O %O\n", paper, edition); _papers[paper]->published_editions[edition - 1]->num_sold++; _papers[paper]->published_editions[edition - 1]->total_revenue += cost; save_me(); } /* add_edition_web_hit() */ /** * This method returns the number of papers which have been sold. * @param paper the paper which was sold * @param edition the edition to check * @return the number of papers that have been sold */ int query_edition_num_sold(string paper, int edition) { if (!is_valid_edition(paper, edition)) { return 0; } return _papers[paper]->published_editions[edition - 1]->num_sold; } /* query_edition_num_sold() */ /** * This method returns the number of web hits for the editon. * @param paper the paper which was hit * @param edition the edition to check * @return the number of web hits on the edition */ int query_edition_num_web_hits(string paper, int edition) { if (!is_valid_edition(paper, edition)) { return 0; } return _papers[paper]->published_editions[edition - 1]->num_web_hits; } /* query_edition_num_web_hits() */ /** * This method checks to see if the area exists or not. * @param area the area to check for */ int is_paper_area(string area) { return pointerp(_areas[area]); } /* is_paper_area() */ /** * This method adds a paper area. * @param area the area to add */ void add_paper_area(string area) { if (is_paper_area(area)) { return ; } _areas[area] = ({ }); } /* add_paper_area() */ /** * This method adds a paper to a paper area. * @param paper the paper to add to the area * @param area the area to add the paper to */ void add_paper_to_area(string paper, string area) { if (!is_paper(paper) || !is_paper_area(area)) { return ; } _areas[area] += ({ paper }); save_me(); } /* add_paper_to_area() */ /** * This method returns all the articles in the specified paper area. * @param area the area to lookup * @return the papers in the area, returns a null array when there are no papers */ string* query_papers_in_area(string area) { if (_areas[area]) { return _areas[area]; } return ({ }); } /* query_papers_in_area() */ /** * This moves the data for the article into the correct location. * @param article the article to set the text for * @param text the text to set */ void set_article_text(class article art, string text) { unguarded( (: write_file(SAVE_DIR + $(art->file_name), save_variable(({ $(art), $(text) })), 1) :) ); } /* set_article_text() */ /** * This method adds an object to be informed of a paper being published. * When the paper is published, the function event_publish_paper, * is called on all the objects in this list. * @param paper the paper to be informed about * @param ob the object to be informed */ void add_newspaper_inform(string paper, string ob) { if (!_inform[paper]) { _inform[paper] = ({ }); } if (!stringp(ob)) { return ; } if (member_array(ob, _inform[paper]) != -1) { return ; } _inform[paper] += ({ ob }); save_me(); } /* add_newspaper_infom() */ /** * This method removes an object to be informed of a paper being published. * @param paper the paper to no longer be informed about * @param ob the object to no longer be informed */ void remove_newspaper_inform(string paper, string ob) { if (!_inform[paper]) { return ; } _inform[paper] -= ({ ob }); save_me(); } /* remove_newspaper_infom() */ /** * This method returns the list of objects that want to be informed about * this paper. * @param paper the paper to be informed about * @return the list of objects to inform */ string* query_newspaper_informs(string paper) { if (!_inform[paper]) { return ({ }); } return _inform[paper]; } /* query_newspaper_informs() */ /** * This method reads in the data associated with the specified article. * @param article the article to read the text for * @return the article text */ string query_article_text(class article art) { string str; string* bits; str = unguarded( (: read_file(SAVE_DIR + $(art->file_name)) :) ); if (str) { bits = restore_variable(str); return bits[1]; } return "Error reading the article text."; } /* query_article_text() */ /** * This method reads in the data associated with the specified article * in html. * @param article the article to read the text for * @return the article text */ string query_article_text_html(class article art) { string str; string* bits; str = unguarded( (: read_file(SAVE_DIR + $(art->file_name)) :) ); if (str) { bits = restore_variable(str); switch (art->type & NEWSPAPER_ARTICLE_TYPE_MASK) { case NEWSPAPER_ARTICLE_TYPE_PLAIN : bits[1] = replace_string(bits[1], "\n\n", "<p>"); bits[1] = replace_string(bits[1], "\n", "<br>"); return bits[1]; case NEWSPAPER_ARTICLE_TYPE_HTML : bits[1] = replace_string(bits[1], "<pre>", "</font><pre>"); bits[1] = replace_string(bits[1], "</pre>", "</pre>\n<font face=\"helvetica,arial\">"); return bits[1]; } return bits[1]; } return "Error reading the article text."; } /* query_article_text_html() */ /** * This method changes an input string into a 'nroff' equivilant output * string. * @param str the string to convert */ string convert_html(string input) { return AUTODOC_NROFF->convert_html(input); } /* convert_html() */ /** * This method reads in the data associated with the specified article * in plain output. * @param article the article to read the text for * @return the article text */ string query_article_text_plain(class article art) { string str; string fluff; string* bits; switch (art->type & NEWSPAPER_ARTICLE_TYPE_MASK) { case NEWSPAPER_ARTICLE_TYPE_SECTION : return ""; case NEWSPAPER_ARTICLE_TYPE_PLAIN : str = unguarded( (: read_file(SAVE_DIR + $(art->file_name)) :) ); if (str) { bits = restore_variable(str); return bits[1]; } break; case NEWSPAPER_ARTICLE_TYPE_HTML : // Check and see if we have an nroff file already. fluff = unguarded( (: NROFF_HAND->cat_file(SAVE_DIR + $(art->file_name) + ".nroff", 1) :) ); if (!fluff) { // Make the html output. str = unguarded( (: read_file(SAVE_DIR + $(art->file_name)) :) ); if (str) { bits = restore_variable(str); bits[1] = convert_html(bits[1]); unguarded( (: write_file(SAVE_DIR + $(art->file_name) + ".proc", $(bits[1]), 1) :) ); unguarded( (: NROFF_HAND->create_nroff(SAVE_DIR + $(art->file_name) + ".proc", SAVE_DIR + $(art->file_name) + ".nroff") :) ); str = unguarded( (: NROFF_HAND->cat_file(SAVE_DIR + $(art->file_name) + ".nroff") :) ); return str; } } else { return fluff; } } return "Error reading the article text."; } /* query_article_text_plain() */ /** * This method returns the long description of the paper. The long * description is used in the newspapers around the place as it's * description. * @param paper the paper to get the long for */ string query_paper_long(string paper) { if (!is_paper(paper)) { return "This is a very transperant and unhappy newspaper.\n"; } return _papers[paper]->long; } /* query_paper_long() */ /** * This method sets the description of the paper. The description is * what is shown on the web page for the paper. * @param paper the paper to set the long for * @param long the new long description of the paper */ void set_paper_description(string paper, string description) { if (!is_paper(paper)) { return ; } _papers[paper]->description = description; save_me(); } /* set_paper_description() */ /** * This method returns the description description of the paper. The long * description is used in the newspapers around the place as it's * description. * @param paper the paper to get the long for */ string query_paper_description(string paper) { if (!is_paper(paper)) { return "This is a very transperant and unhappy newspaper.\n"; } return _papers[paper]->description; } /* query_paper_description() */ /** * This method sets the long of the paper. The long description is * used in the newspapers around the place. * @param paper the paper to set the long for * @param long the new long description of the paper */ void set_paper_long(string paper, string long) { if (!is_paper(paper)) { return ; } _papers[paper]->long = long; save_me(); } /* set_paper_long() */ /** * This method sets the cost at which the paper will be sold. * @param paper the paper to set the cost of * @param cost the new cost of the paper */ void set_paper_cost(string paper, int cost) { if (!is_paper(paper)) { return ; } _papers[paper]->paper_cost = cost; save_me(); } /* set_paper_cost() */ /** * This method returns the cost at which the paper will be sold. * @param paper the paper to set the cost of * @return the cost at which the paper will be sold */ int query_paper_cost(string paper) { if (!is_paper(paper)) { return 0; } return _papers[paper]->paper_cost; } /* set_paper_cost() */ /** * This method publishes a new edition of the specified paper. * @param paper the paper to publish an edition of * @param articles the articles in the paper * @param text the corresponding text to the articles * @param adds the adverts in the paper * @return 1 if successful, 0 if not */ int publish_paper(string paper, string headline, class article* articles, string* text, class advert* adds, string* editors) { string paper_dir; string tmp; class paper fluff; class article article; class edition womble; int i; int edition; int total_xp; int type; if (!is_paper(paper)) { return 0; } fluff = _papers[paper]; edition = sizeof(fluff->published_editions) + 1; paper_dir = SAVE_DIR + fluff->dir_name; unguarded( (: mkdir($(paper_dir)) :)); paper_dir += "/" + edition; unguarded( (: mkdir($(paper_dir)) :)); foreach (article in articles) { article->file_name = fluff->dir_name + "/" + edition + "/" + article->file_name; type = article->type & NEWSPAPER_ARTICLE_TYPE_MASK; // Do not give xp for adds or sections. if ((type == NEWSPAPER_ARTICLE_TYPE_PLAIN || type == NEWSPAPER_ARTICLE_TYPE_HTML) && !(article->type & NEWSPAPER_ARTICLE_NO_XP_FLAG)) { _xp[lower_case(article->author)] += NEWSPAPER_XP_PER_ARTICLE; total_xp += NEWSPAPER_XP_PER_ARTICLE; } } // make it 10% total_xp = total_xp * 10 / 100; total_xp += NEWSPAPER_XP_EDITOR; if (sizeof(editors)) { foreach (tmp in editors) { _xp[tmp] += total_xp / sizeof(editors); } } // Copy the article data into the relevant place. for (i = 0; i < sizeof(articles); i++) { set_article_text(articles[i], text[i]); } womble = new(class edition); womble->articles = articles; womble->adverts = adds; womble->date_published = time(); womble->headline = headline; fluff->published_editions += ({ womble }); save_me(); foreach (tmp in query_newspaper_informs(paper)) { call_out((: $1->event_publish_paper($2) :), 2, tmp, paper); } return 1; } /* publish_paper() */ /** @ignore yes */ void load_me() { string paper; class paper fluff; class paper rabbit; //class edition green; //class article igloo; //int i; unguarded( (: restore_object(SAVE_DIR + "main", 1) :) ); foreach (paper, fluff in _papers) { if (sizeof(fluff) == 6) { rabbit = new(class paper); rabbit->published_editions = fluff->published_editions; rabbit->dir_name = fluff->dir_name; rabbit->long = fluff->long; rabbit->description = fluff->description; rabbit->office = fluff->office; rabbit->paper_cost = 5 * 4; rabbit->language = "general"; _papers[paper] = rabbit; fluff = rabbit; } else if( sizeof( fluff ) == 7 ) { rabbit = new(class paper); rabbit->published_editions = fluff->published_editions; rabbit->dir_name = fluff->dir_name; rabbit->long = fluff->long; rabbit->description = fluff->description; rabbit->office = fluff->office; rabbit->paper_cost = 5 * 4; rabbit->language = fluff->language; _papers[paper] = rabbit; fluff = rabbit; } /* foreach (green in fluff->published_editions) { for (i = 0; i < sizeof(green->articles); i++) { if (sizeof(green->articles[i]) == 6) { igloo = new(class article); igloo->file_name = green->articles[i]->file_name; igloo->title = green->articles[i]->title; igloo->author = green->articles[i]->author; igloo->date_written = green->articles[i]->date_written; igloo->type = green->articles[i]->type; igloo->shown_name = green->articles[i]->shown_name; igloo->colour = 0; green->articles[i] = igloo; } } } */ /* for (i = 0; i < sizeof(fluff->published_editions); i++) { if (sizeof(fluff->published_editions[i]) == 4) { green = new(class edition); green->date_published = fluff->published_editions[i]->date_published; green->articles = fluff->published_editions[i]->articles; green->adverts = fluff->published_editions[i]->adverts; green->headline = fluff->published_editions[i]->headline; fluff->published_editions[i] = green; } } */ } } /* load_me() */ /** @ignore yes */ void save_me() { unguarded( (: save_object(SAVE_DIR + "main") :) ); } /* save_me() */ /** @ignore yes */ mixed* stats() { string paper; string person; class paper data; mixed* ret; int last; int xp; ret = ({ }); foreach (paper, data in _papers) { last = query_last_edition_num(paper); ret += ({ ({ paper + ": office", data->office }), ({ paper + ": dir name", data->dir_name }), ({ paper + ": last issue", last }), ({ paper + ": current issue", query_current_edition_num(paper) }), ({ paper + ": num sold", query_edition_num_sold(paper, last) }), ({ paper + ": num web hits", query_edition_num_web_hits(paper, last) }), ({ paper + ": revenue", query_edition_revenue(paper, last) }), }); } foreach (person, xp in _xp) { ret += ({ ({ person + ": xp", xp }) }); } return ret; } /* stats() */ /** * @ignore yes * This is the login function to check the person for any exciting things like * waiting for xp. */ void player_login_check(string player, string bing) { object play; int xp; if (bing != LOGIN) { return ; } xp = _xp[player]; if (xp) { play = find_player(player); play->adjust_xp(xp); map_delete(_xp, player); save_me(); tell_object(play, "%^YELLOW%^You feel like the experience of writing " "an article has made you a better person.\n%^RESET%^"); } } /* player_login_check() */ /** * This function sets the language for the given paper. * @param paper The name of the paper. * @param language The language to use. */ void set_language_for( string paper, string language ) { if( is_paper( paper ) ) _papers[ paper ]->language = language; } /* void set_language_for() */ /** * This function returns the language for the given newspaper. * @param paper The name of the paper. * @return The language for the paper, "general" for none or 0 if for error */ string query_language_for( string paper ) { if( is_paper( paper ) ) { if( !undefinedp( _papers[ paper ]->language ) ) return _papers[ paper ]->language; return "general"; } return 0; } /* string query_language_for() */