ChannelTextParser.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <common/ChannelTextParser.h>
00022 #include <engine/ScorchedContext.h>
00023 #include <tank/TankContainer.h>
00024 #include <lang/LangResource.h>
00025 
00026 ChannelTextParser::ChannelTextParser()
00027 {
00028 }
00029 
00030 ChannelTextParser::~ChannelTextParser()
00031 {
00032 }
00033 
00034 ChannelTextParser::ChannelTextEntry *ChannelTextParser::getEntry(int position)
00035 {
00036         if (position >= (int) entryIndex_.size()) return 0;
00037 
00038         unsigned int index = entryIndex_[position];
00039         if (index == 0) return 0;
00040 
00041         ChannelTextEntry &textEntry = entries_[index - 1];
00042         return &textEntry;
00043 }
00044 
00045 void ChannelTextParser::subset(ChannelTextParser &other, int start, int len)
00046 {
00047         entries_ = other.entries_;
00048 
00049         // Create this channel text from a subset of another channel text
00050         for (int i=start; i<start+len; i++)
00051         {
00052                 text_.push_back(other.text_.c_str()[i]);
00053                 entryIndex_.push_back(other.entryIndex_[i]);
00054         }
00055 }
00056 
00057 void ChannelTextParser::addIndex(int number, unsigned char index)
00058 {
00059         for (int i=0; i<number; i++)
00060         {
00061                 entryIndex_.push_back(index);
00062         }
00063 }
00064 
00065 void ChannelTextParser::parseText(ScorchedContext &context, const LangString &text)
00066 {
00067         // Clear any existing items
00068         text_.clear();
00069         entryIndex_.clear();
00070         entries_.clear();
00071 
00072         // Parse out all of the urls
00073         const unsigned int *pos = text.c_str();
00074         const unsigned int *start = 0;
00075 
00076         // Find the next [
00077         while (start = LangStringUtil::strstr(pos, LANG_STRING("[")))
00078         {
00079                 // Add all text before [
00080                 text_.append(pos, start - pos);
00081                 addIndex(start - pos, 0);
00082                 pos = start; // Skip to this point
00083 
00084                 // Find the next ]
00085                 const unsigned int *end = LangStringUtil::strstr(start, LANG_STRING("]"));
00086                 if (end)
00087                 {
00088                         // Create the url
00089                         LangString url;
00090                         url.append(pos, end - pos + 1);
00091 
00092                         // Parse the url
00093                         ChannelTextEntry newEntry;
00094                         if (parseUrl(context, url, newEntry))
00095                         {
00096                                 // Update the entryIndex array to point to the newEntry
00097                                 entries_.push_back(newEntry);
00098                                 addIndex((int) newEntry.text.size(), (unsigned char) entries_.size());
00099 
00100                                 // Add the new url text
00101                                 text_.append(newEntry.text);
00102                         }
00103                         else
00104                         {
00105                                 // Add the normal text
00106                                 text_.append(url);
00107                                 addIndex((int) url.size(), 0);
00108                         }
00109 
00110                         // Skip the url
00111                         pos = end + 1;
00112                 }
00113         }
00114 
00115         // Add all remaining text
00116         text_.append(pos);
00117         addIndex(LangStringUtil::strlen(pos), 0);
00118 }
00119 
00120 bool ChannelTextParser::parseUrl(ScorchedContext &context, 
00121         const LangString &url, ChannelTextEntry &entry)
00122 {
00123         // Find the url seperator
00124         const unsigned int *colon = LangStringUtil::strstr(url.c_str(), LANG_STRING(":"));
00125         if (!colon) return false;
00126 
00127         // Strip the [] chars and the :
00128         LangString urlPart(url.c_str() + 1, colon - url.c_str() - 1);
00129         LangString otherPart(colon + 1, LangStringUtil::strlen(colon) - 2);
00130         entry.part = otherPart;
00131 
00132         // Find a url handler based on the url
00133         // Hardcoded for now
00134         if (urlPart == LANG_STRING("c")) // A channel
00135         {
00136                 return createChannelEntry(context, otherPart, entry);
00137         }
00138         else if (urlPart == LANG_STRING("p")) // A player
00139         {
00140                 return createPlayerEntry(context, otherPart, entry);
00141         }
00142         else if (urlPart == LANG_STRING("t")) // A tip
00143         {
00144                 return createTipEntry(context, otherPart, entry);
00145         }
00146         else if (urlPart == LANG_STRING("w")) // A weapon
00147         {
00148                 return createWeaponEntry(context, otherPart, entry);
00149         } 
00150         else if (urlPart == LANG_STRING("a")) // An admin
00151         {
00152                 return createAdminEntry(context, otherPart, entry);
00153         }
00154         return false;
00155 }
00156 
00157 bool ChannelTextParser::createPlayerEntry(ScorchedContext &context, 
00158         const LangString &part, ChannelTextEntry &entry)
00159 {
00160         entry.type = ePlayerEntry;
00161         entry.text.push_back('[');
00162         entry.text.append(part);
00163         entry.text.push_back(']');
00164         entry.data = 0;
00165 
00166         Tank *tank = context.getTankContainer().getTankByName(part);
00167         if (tank)
00168         {
00169                 entry.data = tank->getPlayerId();
00170                 entry.color = tank->getColor();
00171         }
00172 
00173         return true;
00174 }
00175 
00176 bool ChannelTextParser::createWeaponEntry(ScorchedContext &context, 
00177         const LangString &part, ChannelTextEntry &entry)
00178 {
00179         entry.type = eWeaponEntry;
00180         entry.text.push_back('[');
00181         entry.text.append(part);
00182         entry.text.push_back(']');
00183         entry.color = Vector(1.0f, 1.0f, 1.0f);
00184 
00185         return true;
00186 }
00187 
00188 bool ChannelTextParser::createTipEntry(ScorchedContext &context, 
00189         const LangString &part, ChannelTextEntry &entry)
00190 {
00191         entry.type = eTipEntry;
00192         entry.text = part;
00193         entry.color = Vector(1.0f, 1.0f, 0.0f);
00194 
00195         return true;
00196 }
00197 
00198 bool ChannelTextParser::createChannelEntry(ScorchedContext &context, 
00199         const LangString &part, ChannelTextEntry &entry)
00200 {
00201         entry.type = eChannelEntry;
00202         entry.text.push_back('[');
00203         entry.text.append(part);
00204         entry.text.push_back(']');
00205 
00206         return true;
00207 }
00208 
00209 bool ChannelTextParser::createAdminEntry(ScorchedContext &context, 
00210         const LangString &part, ChannelTextEntry &entry)
00211 {
00212         entry.type = eAdminEntry;
00213         entry.text.append(part);
00214         entry.text.push_back(' ');
00215         entry.text.append(LANG_RESOURCE("ADMIN_BRK", "(Admin)"));
00216         entry.color = Vector(1.0f, 1.0f, 1.0f);
00217 
00218         return true;
00219 }

Generated on Mon Feb 16 15:14:48 2009 for Scorched3D by  doxygen 1.5.3