//---------------------------------------------------------------------------- bool SceneBuilder::ConvertFloatAttrib (IParamBlock2* paramBlock, int index, std::string &name, float &value) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if(!paramDesc) return false; ParamDef ¶mDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); float floatValue; Interval validInverval; BOOL retrieved = paramBlock->GetValue((ParamID)index, 0, floatValue, validInverval); if(!retrieved) { return false; } char *valueName = paramDef.int_name; if (!IsValidName(valueName)) { valueName = paramBlock->GetLocalName((ParamID)index); assertion(IsValidName(valueName), "valueName must be valuable."); } name = std::string(valueName); //if (!HasAnimation(paramBlock, index)) { value = floatValue; return true; } return true; }
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertIntListBoxAttrib (IParamBlock2* paramBlock, int index, std::string &name, int &value) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if (!paramDesc) return false; ParamDef& paramDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); int intValue; Interval validInverval; BOOL retrieved = false; retrieved = paramBlock->GetValue((ParamID)index, 0, intValue, validInverval); if (retrieved) { char* valueName = paramDef.int_name; if (!IsValidName(valueName)) { valueName = paramBlock->GetLocalName((ParamID)index); assertion(IsValidName(valueName), "valueName must be valuable."); } name = std::string(valueName); //3ds Max中数组从1开始,这里的index要减1 value = (intValue==-1) ? -1 : (intValue-1); } return true; }
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertFRGBAAttrib(IParamBlock2* paramBlock, int index, std::string &name, PX2::Float4 &value) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if (!paramDesc) return false; ParamDef ¶mDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); Point4 vectorValue; Interval validInterval; BOOL retrieved = false; retrieved = paramBlock->GetValue((ParamID)index, 0 , vectorValue, validInterval); if(retrieved) { TCHAR* valueName = paramDef.int_name; if (!IsValidName(valueName)) valueName = paramBlock->GetLocalName((ParamID)index ); assertion(IsValidName(valueName), "valueName must be valuable."); name = std::string(valueName); value = PX2::Float4(vectorValue.x, vectorValue.y, vectorValue.z, vectorValue.w); if(HasAnimation(paramBlock, index)) { } } return true; }
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertBitMapAttrib(IParamBlock2* paramBlock, int index, std::string &name, PX2::Texture2D *&tex2d) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if (!paramDesc) return false; ParamDef ¶mDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); PX2_UNUSED(paramDef); PBBitmap *pb; Interval validInterval; char *valueName = 0; PX2_UNUSED(valueName); BOOL retrieved = false; retrieved = paramBlock->GetValue((ParamID)index, 0, pb, validInterval); char strBitMapName[256]; memset(strBitMapName, 0, 256*sizeof(char)); if (pb) { if (BMMGetFullFilename(&pb->bi) == TRUE) { strcpy(strBitMapName, pb->bi.Name()); std::string resourcePath; std::string fullName = std::string(strBitMapName); std::string::size_type sizeT = fullName.find_first_not_of(mSettings->SrcRootDir); resourcePath = std::string(strBitMapName).substr(sizeT); tex2d = PX2::DynamicCast<PX2::Texture2D>( PX2::ResourceManager::GetSingleton().BlockLoad(strBitMapName)); tex2d->SetResourcePath(resourcePath); } } if (retrieved) { valueName = paramDef.int_name; if (!IsValidName(valueName)) valueName = paramBlock->GetLocalName((ParamID)index); assertion(IsValidName(valueName), "valueName must be valuable."); name = valueName; } return true; }
void CUser::NewCharToAgent(Packet & pkt) { Packet result(WIZ_NEW_CHAR); uint32 nHair; uint16 sClass; uint8 bCharIndex, bRace, bFace, str, sta, dex, intel, cha, errorCode = 0; std::string strUserID; pkt >> bCharIndex >> strUserID >> bRace >> sClass >> bFace >> nHair >> str >> sta >> dex >> intel >> cha; _CLASS_COEFFICIENT* p_TableCoefficient = g_pMain->m_CoefficientArray.GetData(sClass); if (!IsValidName(strUserID.c_str())) errorCode = NEWCHAR_INVALID_NAME; else if (bCharIndex > 2) errorCode = NEWCHAR_NO_MORE; else if (p_TableCoefficient == NULL || (str + sta + dex + intel + cha) > 300) errorCode = NEWCHAR_INVALID_DETAILS; else if (str < 50 || sta < 50 || dex < 50 || intel < 50 || cha < 50) errorCode = NEWCHAR_STAT_TOO_LOW; if (errorCode != 0) { result << errorCode; Send(&result); return; } result << m_strAccountID << bCharIndex << strUserID << bRace << sClass << bFace << nHair << str << sta << dex << intel << cha; g_pMain->m_LoggerSendQueue.PutData(&result, GetSocketID()); }
/* static */ BOOL XMLUtils::IsValidQName(XMLVersion version, const uni_char *name, unsigned name_length) { if (name_length == ~0u) name_length = uni_strlen(name); if (!IsValidName(version, name, name_length)) return FALSE; if (XMLUtils::GetNextCharacter(name, name_length) == ':') return FALSE; while (name_length != 0) if (XMLUtils::GetNextCharacter(name, name_length) == ':') { if (name_length == 0) return FALSE; while (name_length != 0) if (XMLUtils::GetNextCharacter(name, name_length) == ':') return FALSE; return TRUE; } return TRUE; }
bool CChat::CreateChannel(LPCTSTR pszName, LPCTSTR pszPassword, CChatMember *pMember) { ADDTOCALLSTACK("CChat::CreateChannel"); if ( pMember ) { CClient *pClient = pMember->GetClient(); if ( pClient && !pClient->IsPriv(PRIV_GM) && !(g_Cfg.m_iChatFlags & CHATF_CHANNELCREATION) ) { CGString sName; FormatName(sName, NULL, true); pMember->SendChatMsg(CHATMSG_PlayerMessage, sName, " Channel creation is disabled."); return false; } } if ( !IsValidName(pszName, false) ) { if ( pMember ) pMember->SendChatMsg(CHATMSG_InvalidConferenceName); return false; } else if ( FindChannel(pszName) ) { if ( pMember ) pMember->SendChatMsg(CHATMSG_DuplicatedConferenceName); return false; } CChatChannel *pChannel = new CChatChannel(pszName, pszPassword, !pMember); m_Channels.InsertTail(pChannel); BroadcastAddChannel(pChannel); if ( pMember && (g_Cfg.m_iChatFlags & CHATF_CHANNELMODERATION) ) pChannel->SetModerator(pMember->GetChatName()); return true; }
void CMUSHclientDoc::MXP_collected_entity (void) { m_strMXPstring.TrimLeft (); m_strMXPstring.TrimRight (); // case insensitive // m_strMXPstring.MakeLower (); // count them m_iMXPentities++; // TRACE1 ("MXP collected entity %s\n", (LPCTSTR) m_strMXPstring); MXP_error (DBG_ALL, msgMXP_CollectedEntity, TFormat ("MXP entity: &%s;", (LPCTSTR) m_strMXPstring)); if (!IsValidName (m_strMXPstring) && m_strMXPstring.Left (1) != "#") { MXP_error (DBG_ERROR, errMXP_InvalidEntityName, TFormat ("Invalid MXP entity name \"%s\" supplied.", m_strMXPstring)); return; } // see if we know of this entity CString strEntityContents = MXP_GetEntity (m_strMXPstring); if (!strEntityContents.IsEmpty ()) AddToLine (strEntityContents, 0); } // end of CMUSHclientDoc::MXP_collected_entity
// returns: 0 - success, 1 - fail Int32 ZigbeeDoorSensor::SetHistoryFileName( /* [in] */ const String& filename) { if (!IsValidName(filename)) return 1; mHistoryRecordFileName = filename; return 0; }
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertFloatTabAttrib (IParamBlock2* paramBlock, int index, std::string &name, float *table) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if (!paramDesc) return false; ParamDef& paramDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); Interval validInterval; BOOL retrieved = true; int count = paramBlock->Count(paramDesc->IndextoID(index)); if (count == 0) return false; float* floats = new float[count]; IParamBlock2* params = paramBlock; for (int i=0; i<count; i++) { retrieved &= params->GetValue((ParamID)index, 0 , floats[i], validInterval, i); } if (retrieved && count > 0) { TCHAR* valueName = paramDef.int_name; if (!IsValidName(valueName)) { valueName = paramBlock->GetLocalName((ParamID)index); assertion(IsValidName(valueName), "valueName must be valuable."); } name = std::string(valueName); for (int i=0; i<count; i++) { table[i] = floats[i]; } } return true; }
/** Return if the value string is valid. @param[in] Value The value to be checked. @param[in] Length The length of value string in bytes. @retval TRUE The name string is valid. @retval FALSE The name string is invalid. **/ BOOLEAN IsValidValue ( IN CHAR8 *Value, IN UINTN Length ) { if (IsValidName(Value, Length) || IsValidGuid(Value, Length)) { return TRUE; } return FALSE; }
BOOL CIconCache::Add(const CString& sName, const CString& sImagePath, COLORREF crBack) { if (IsValidName(sName) && !sImagePath.IsEmpty()) { HICON hIcon = CEnBitmap::LoadImageFileAsIcon(sImagePath, crBack, m_sizeIcon.cx, m_sizeIcon.cy); return Add(sName, hIcon); } ASSERT(0); return FALSE; }
Epoch MpcorbEphemeris::GetReferenceEpoch(const std::string& name) { if (IsValidName(name)) { UpdateReference(name); return m_referenceEpoch; } else { OTL_ERROR() << "Name " << Bracket(name) << " not found"; } return Epoch(); }
BOOL CIconCache::Add(const CString& sName, HBITMAP hbm, COLORREF crMask) { if (IsValidName(sName) && hbm) { HICON hIcon = CEnBitmap::ExtractIcon(hbm, crMask, m_sizeIcon.cx, m_sizeIcon.cy); ASSERT(hIcon); return Add(sName, hIcon); } ASSERT(0); return FALSE; }
OrbitalElements MpcorbEphemeris::GetReferenceOrbitalElements(const std::string& name) { if (IsValidName(name)) { UpdateReference(name); return m_referenceOrbitalElements; } else { OTL_ERROR() << "Name " << Bracket(name) << " not found"; } return OrbitalElements(); }
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertStringAttrib (IParamBlock2 *paramBlock, int index, std::string &name, std::string &str) { PX2_UNUSED(name); PX2_UNUSED(str); ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); if (!paramDesc) return false; ParamDef ¶mDef = paramDesc->GetParamDef(paramDesc->IndextoID(index)); char *stringValue; Interval validInverval; BOOL retrieved = false; retrieved = paramBlock->GetValue((ParamID)index, 0, stringValue, validInverval); if (retrieved) { char* valueName = paramDef.int_name; if (!IsValidName(valueName)) { valueName = paramBlock->GetLocalName((ParamID)index); } assertion(IsValidName(valueName), "valueName must be valuable."); name = valueName; PX2_UNUSED(name); assertion(false, ""); } return true; }
bool DeclareVar(CompileInstance &inst, const mtlChars &type, const mtlChars &name, const mtlChars &expr) { const TypeInfo *type_info = GetTypeInfo(type); if (type_info == NULL) { AddError(inst, "Unknown type", type); return false; } if (!IsValidName(name)) { AddError(inst, "Invalid name", name); return false; } const Definition *prev_def = GetType(inst, name); if (prev_def != NULL) { AddError(inst, "Redeclaration", name); return false; } const int rel_sptr = inst.scopes.GetLast()->GetItem().rel_sptr; Definition &def = inst.scopes.GetLast()->GetItem().defs.AddLast(); def.name.Copy(name); def.mut = Mutable; def.type = *type_info; def.scope_level = inst.scopes.GetSize() - 1; def.value.var_addr = rel_sptr; //def.values.Create(type_info->size); //for (int addr_offset = 0; addr_offset < type_info->size; ++addr_offset) { // def.values[addr_offset].var_addr = rel_sptr + addr_offset; //} for (int i = 0; i < type_info->size; ++i) { Definition &def = inst.scopes.GetLast()->GetItem().defs.AddLast(); def.name.Copy(name); def.name.Append(Accessor); def.name.Append(Members[i]); def.mut = Mutable; def.type = gSubTypes[type_info->type]; def.scope_level = inst.scopes.GetSize() - 1; def.value.var_addr = rel_sptr + i; } PushStack(inst, type_info->size); return (expr.GetSize() > 0) ? AssignVar(inst, name, expr) : true; }
void CChat::CreateJoinChannel(CChatChanMember * pByMember, LPCTSTR pszName, LPCTSTR pszPassword) { ADDTOCALLSTACK("CChat::CreateJoinChannel"); if ( ! IsValidName( pszName, false )) { pByMember->GetClient()->addChatSystemMessage( CHATMSG_InvalidConferenceName ); } else if (IsDuplicateChannelName(pszName)) { pByMember->GetClient()->addChatSystemMessage( CHATMSG_AlreadyAConference ); } else { if ( CreateChannel(pszName, ((pszPassword != NULL) ? pszPassword : ""), pByMember)) JoinChannel(pByMember, pszName, ((pszPassword != NULL) ? pszPassword : "")); } }
BOOL CIconCache::Add(const CString& sName, HICON hIcon) { if (IsValidName(sName) && hIcon) { // create image list first time only if (m_ilImages.GetSafeHandle() || m_ilImages.Create(m_sizeIcon.cx, m_sizeIcon.cy, ILC_COLOR32 | ILC_MASK, 0, 1)) { int nImage = m_ilImages.Add(hIcon); if (nImage >= 0) { m_mapIndices[sName] = nImage; return TRUE; } } } ASSERT(0); return FALSE; }
void CMUSHclientDoc::MXP_collected_entity (void) { m_strMXPstring.TrimLeft (); m_strMXPstring.TrimRight (); // case insensitive // m_strMXPstring.MakeLower (); // count them m_iMXPentities++; // TRACE1 ("MXP collected entity %s\n", (LPCTSTR) m_strMXPstring); MXP_error (DBG_ALL, msgMXP_CollectedEntity, TFormat ("MXP entity: &%s;", (LPCTSTR) m_strMXPstring)); if (!IsValidName (m_strMXPstring) && m_strMXPstring.Left (1) != "#") { MXP_error (DBG_ERROR, errMXP_InvalidEntityName, TFormat ("Invalid MXP entity name \"%s\" supplied.", m_strMXPstring)); return; } // see if we know of this entity CString strEntityContents = MXP_GetEntity (m_strMXPstring); if (!strEntityContents.IsEmpty ()) { // if the entity happens to be < & > etc. don't reprocess it m_bMXP = false; DisplayMsg (strEntityContents, strEntityContents.GetLength (), 0); m_bMXP = true; } } // end of CMUSHclientDoc::MXP_collected_entity
void CMUSHclientDoc::MXP_Definition (CString strTag) { bool bSecure = MXP_Secure (); MXP_Restore_Mode (); // cancel secure-once mode // check in secure mode if (DEFINITIONS_MUST_BE_SECURE && !bSecure) { MXP_error (DBG_ERROR, errMXP_DefinitionWhenNotSecure, TFormat ("MXP definition ignored when not in secure mode: <!%s>" , (LPCTSTR) strTag)); return; } CString strDefinition; // get first word (eg. ELEMENT or ENTITY) GetWord (strDefinition, strTag); if (!IsValidName (strDefinition)) { MXP_error (DBG_ERROR, errMXP_InvalidDefinition, TFormat ("Invalid MXP definition name: <!%s>", (LPCTSTR) m_strMXPstring)); return; } strDefinition.MakeLower (); // case-insensitive? // get name of what we are defining CString strName; GetWord (strName, strTag); if (!IsValidName (strName)) { MXP_error (DBG_ERROR, errMXP_InvalidElementName, TFormat ("Invalid MXP element/entity name: \"%s\"", (LPCTSTR) strName)); return; } /* if (m_bPuebloActive) { MXP_error (DBG_ERROR, errMXP_DefinitionAttemptInPueblo, TFormat ("Defining elements/entities not valid in Pueblo: <%s>", (LPCTSTR) strName)); return; } */ // debugging MXP_error (DBG_INFO, msgMXP_GotDefinition, TFormat ("Got Definition: !%s %s %s", (LPCTSTR) strDefinition, (LPCTSTR) strName, (LPCTSTR) strTag)); if (strDefinition == "element" || strDefinition == "el") MXP_Element (strName, strTag); else if (strDefinition == "entity" || strDefinition == "en") MXP_Entity (strName, strTag); else if (strDefinition == "attlist" || strDefinition == "at") MXP_Attlist (strName, strTag); else MXP_error (DBG_ERROR, errMXP_InvalidDefinition, TFormat ("Unknown definition type: <!%s>", (LPCTSTR) strDefinition)); } // end of CMUSHclientDoc::MXP_Definition
/* * schema_create - create and initialize a schema * * - allocate memory for the schema, application shall later call * schema_destroy to clean up * - parse the definition string; * - empty defstring create a stub schema for schema_fromascii * - return pointer to a schema if OK, NULL on error * */ schema_t *schema_create(const char *defstring) { schema_t *schema; char *dupstring, *saveptr, *name, *type; int offset, fieldind; int tempsize, failed; field_t *newtable; /* allocate memory */ if ((schema = (schema_t *)malloc(sizeof(schema_t))) == NULL) { perror("schema_create: malloc"); return NULL; } /* check whether we should proceed to parse the definition string */ if (defstring == NULL) { return schema; } else if ((dupstring = strdup(defstring)) == NULL) { /* remember to duplicate the string for strtok_r */ perror("schema_create: strdup"); return NULL; } schema->endian = xplatform_testendian(); schema->fieldnum = 0; schema->field = NULL; /* allocate field table with a tempsize (8); we need to further expand the table or shrink as more or less fields are actually parsed */ tempsize = 8; schema->field = (field_t *)malloc(tempsize * sizeof(field_t)); if (schema->field == NULL) { perror("schema_create: malloc field table"); free(dupstring); free(schema); } /* special treatment for the first field's type since the dupstring has to be passed in as the first argument */ fieldind = 0; offset = 0; type = (char *)strtok_r(dupstring, " ", &saveptr); if (type == NULL) { fprintf(stderr, "schema_create: illegal syntax \"%s\"\n", defstring); free(dupstring); free(schema); return NULL; } /* install the current field entry in the schema table and parse the next one */ failed = 0; schema->fieldnum = 0; while (type != NULL) { /* check whether we shall expand the table */ if (fieldind == tempsize) { tempsize *= 2; newtable = (field_t *)realloc(schema->field, tempsize * sizeof(field_t)); if (newtable == NULL) { perror("schema_create: reallocate field table"); failed = 1; break; } else schema->field = newtable; } /* determine the size of the field */ if ((strcmp(type, "int8_t") == 0) || (strcmp(type, "uint8_t") == 0) || (strcmp(type, "char") == 0)) schema->field[fieldind].size = 1; else if ((strcmp(type, "int16_t") == 0) || (strcmp(type, "uint16_t") == 0)) schema->field[fieldind].size = 2; else if ((strcmp(type, "int32_t") == 0) || (strcmp(type, "uint32_t") == 0) || (strcmp(type, "float32_t") == 0) || (strcmp(type, "float") == 0)) schema->field[fieldind].size = 4; else if ((strcmp(type, "float64_t") == 0) || (strcmp(type, "int64_t") == 0) || (strcmp(type, "uint64_t") == 0) || (strcmp(type, "double") == 0)) schema->field[fieldind].size = 8; else { fprintf(stderr, "schema_create: unknown type \"%s\"\n", type); failed = 1; break; } schema->field[fieldind].offset = offset; offset += schema->field[fieldind].size; /* for the next field */ /* proceed to read in the variable name */ name = (char *)strtok_r(NULL, " ;", &saveptr); if (name == NULL) { fprintf(stderr, "schema_create: variable name missing \"%s\"\n", defstring); failed = 1; break; } /* allocate memory for the field name */ if (!IsValidName(name)) { fprintf(stderr, "schema_create: invalid field name %s\n", name); failed = 1; break; } schema->field[fieldind].name = NULL; schema->field[fieldind].type = NULL; if ((schema->field[fieldind].name = strdup(name)) == NULL) { perror("schema_create: strdup field name"); failed = 1; break; } /* record the type verbatim */ if ((schema->field[fieldind].type = strdup(type)) == NULL) { perror("schema_create: strdup field type"); failed = 1; break; } /* parse the next field's type */ fieldind++; type = (char *)strtok_r(NULL, " ;", &saveptr); } schema->fieldnum = fieldind; free(dupstring); /* must be released no matter what */ if (failed ) { schema_destroy(schema); return NULL; } /* shrink the table if we have over-provisioned */ if (schema->fieldnum < tempsize) { newtable = (field_t *) realloc(schema->field, schema->fieldnum * sizeof(field_t)); if (newtable == NULL) { perror("schema_create: reallocate (shrink) field table"); schema_destroy(schema); return NULL; } schema->field = newtable; } return schema; }
bool CMUSHclientDoc::BuildArgumentList (CArgumentList & ArgumentList, CString strTag) { CArgument * pArgument; int iArgumentNumber = 0; bool bEnd; CString strArgumentName; CString strEquals; CString strArgumentValue; // first get rid of old arguments DELETE_LIST (ArgumentList); // collect all arguments // get first word bEnd = GetWord (strArgumentName, strTag); while (!bEnd) { if (strArgumentName == "/") { strTag.TrimLeft (); if (!strTag.IsEmpty ()) { MXP_error (DBG_ERROR, errMXP_InvalidArgumentName, TFormat ("Invalid parameter name: \"%s\"", (LPCTSTR) strArgumentName)); return true; } // NB - not implemented yet - we have detected an empty tag. // eg. <sound blah blah /> return false; // OK return } // end of / at end of list // #error fix it here ... // is it folllowed by equals? bEnd = GetWord (strEquals, strTag); if (strEquals == "=") // yes { if (!IsValidName (strArgumentName)) // check name valid { MXP_error (DBG_ERROR, errMXP_InvalidArgumentName, TFormat ("Invalid parameter name: \"%s\"", (LPCTSTR) strArgumentName)); return true; } bEnd = GetWord (strArgumentValue, strTag); // so get value if (bEnd) { MXP_error (DBG_ERROR, errMXP_NoArgument, TFormat ("No argument value supplied for: \"%s\"", (LPCTSTR) strArgumentName)); return true; } strArgumentName.MakeLower (); // named arguments don't have a numbered position pArgument = new CArgument (strArgumentName, strArgumentValue, 0); ArgumentList.AddTail (pArgument); bEnd = GetWord (strArgumentName, strTag); // get next argument } // end of name=value else { // positional argument, no name=value // thus, name is value pArgument = new CArgument ("", strArgumentName, ++iArgumentNumber); ArgumentList.AddTail (pArgument); strArgumentName = strEquals; // and strEquals is next argument, if any } // end of value alone } // end of processing each argument return false; // all OK } // end of CMUSHclientDoc::BuildArgumentList
// do the action required to open a single atomic tag (iAction) void CMUSHclientDoc::MXP_OpenAtomicTag (const CString strTag, int iAction, CStyle * pStyle, CString & strAction, // new action CString & strHint, // new hint CString & strVariable, // new variable CArgumentList & ArgumentList) { CString strArgument; CString strArgumentName; bool bIgnoreUnusedArgs = false; // cut down on some spam by setting this COLORREF colour1, colour2; unsigned short iFlags = pStyle->iFlags; COLORREF iForeColour = pStyle->iForeColour; COLORREF iBackColour = pStyle->iBackColour; // call script if required if (m_dispidOnMXP_OpenTag != DISPID_UNKNOWN || m_bPluginProcessesOpenTag) { // dummy-up an argument list CString strArgument; CArgument * pArgument; POSITION pos; // put the arguments into the array for (pos = ArgumentList.GetHeadPosition (); pos; ) { pArgument = ArgumentList.GetNext (pos); // empty ones we will put there by position if (pArgument->strName.IsEmpty ()) strArgument += CFormat ("'%s'", (LPCTSTR) pArgument->strValue); else strArgument += CFormat ("%s='%s'", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue); if (pos) strArgument += " "; } // end of looping through each argument bool bNotWanted = MXP_StartTagScript (strTag, strArgument, ArgumentList); // re-get current style in case the script did a world.note pStyle = m_pCurrentLine->styleList.GetTail (); // put things backt to how they were pStyle->iFlags = iFlags; pStyle->iForeColour = iForeColour; pStyle->iBackColour = iBackColour; if (bNotWanted) return; // they didn't want to go ahead with this tag } // find current foreground and background RGB values GetStyleRGB (pStyle, colour1, colour2); // special processing for Pueblo // a tag like this: <A XCH_CMD="examine #1"> // will convert to a SEND tag if (iAction == MXP_ACTION_HYPERLINK && PUEBLO_ACTIVE) { strArgument = GetArgument (ArgumentList, "xch_cmd", 0, true); if (!strArgument.IsEmpty ()) { m_bPuebloActive = true; // for correct newline processing iAction = MXP_ACTION_SEND; } } // now take the action switch (iAction) { // temporarily make headlines the same as bold case MXP_ACTION_H1: case MXP_ACTION_H2: case MXP_ACTION_H3: case MXP_ACTION_H4: case MXP_ACTION_H5: case MXP_ACTION_H6: case MXP_ACTION_BOLD: pStyle->iFlags |= HILITE; break; case MXP_ACTION_UNDERLINE: pStyle->iFlags |= UNDERLINE; break; case MXP_ACTION_ITALIC: pStyle->iFlags |= BLINK; break; case MXP_ACTION_COLOR: { pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with in case only FORE or BACK supplied pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; // foreground colour strArgument = GetArgument (ArgumentList, "fore", 1, true); // get foreground colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iForeColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); // background colour strArgument = GetArgument (ArgumentList, "back", 2, true); // get background colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iBackColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); } break; // end of COLOR case MXP_ACTION_HIGH: { CColor clr; pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; clr.SetColor (colour1); float lum = clr.GetLuminance (); lum += 0.15f; if (lum > 1.0f) lum = 1.0f; clr.SetLuminance (lum); pStyle->iForeColour = clr; } break; // end of COLOR case MXP_ACTION_SEND: // send to mud hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions if (GetKeyword (ArgumentList, "prompt")) pStyle->iFlags |= ACTION_PROMPT; // prompt action else pStyle->iFlags |= ACTION_SEND; // send-to action if (m_bUnderlineHyperlinks) pStyle->iFlags |= UNDERLINE; // underline it if (m_bUseCustomLinkColour) { // find current background RGB value pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } strArgument = GetArgument (ArgumentList,"href", 1, false); // get link if (strArgument.IsEmpty ()) strArgument = GetArgument (ArgumentList,"xch_cmd", 1, false); // get link strAction = strArgument; // hyperlink strArgument = GetArgument (ArgumentList, "hint", 2, false); // get hints if (strArgument.IsEmpty ()) strArgument = GetArgument (ArgumentList,"xch_hint", 2, false); // get hint strHint = strArgument; // hints break; // end of MXP_ACTION_SEND case MXP_ACTION_HYPERLINK: // hyperlink strArgument = GetArgument (ArgumentList,"href", 1, false); // get link strAction = strArgument; // hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions pStyle->iFlags |= ACTION_HYPERLINK | UNDERLINE; // send-to action if (m_bUseCustomLinkColour) { pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } break; // end of MXP_ACTION_HYPERLINK case MXP_ACTION_FONT: { pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with in case only FORE or BACK supplied pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; // eg. <FONT COLOR=Red,Blink> CStringList list; strArgument = GetArgument (ArgumentList,"color", 1, true); // get color etc. if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"fgcolor", 1, true); // get color StringToList (strArgument, ",", list); // break into components for (POSITION pos = list.GetHeadPosition (); pos; ) { CString strItem = list.GetNext (pos); // get action item if (strItem == "blink") pStyle->iFlags |= BLINK; else if (strItem == "italic") pStyle->iFlags |= BLINK; else if (strItem == "underline") pStyle->iFlags |= UNDERLINE; else if (strItem == "bold") pStyle->iFlags |= HILITE; else if (strItem == "inverse") pStyle->iFlags |= INVERSE; else { // must be colour name, yes? // foreground colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strItem, pStyle->iForeColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strItem)); } // end of colour } // end of handling each item in the list strArgument = GetArgument (ArgumentList,"back", 2, true); // get back color if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"bgcolor", 2, true); // get back color // background colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iBackColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); // get font size argument to avoid warnings about unused arguments strArgument = GetArgument (ArgumentList,"size", 0, true); // get font size } break; // end of FONT case MXP_ACTION_VERSION: { CString strVersion = CFormat ("\x1B[1z<VERSION MXP=\"%s\" CLIENT=MUSHclient " "VERSION=\"%s\" REGISTERED=YES>%s", MXP_VERSION, MUSHCLIENT_VERSION, ENDLINE ); SendPacket (strVersion, strVersion.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_VersionSent, TFormat ("Sent version response: %s" , (LPCTSTR) strVersion.Mid (4))); } break; // end of VERSION case MXP_ACTION_AFK: if (m_bSendMXP_AFK_Response) // if player wants us to { strArgument = GetArgument (ArgumentList,"challenge", 1, false); // get challenge // find time since last player input CTimeSpan ts = CTime::GetCurrentTime() - m_tLastPlayerInput; CString strAFK = CFormat ("\x1B[1z<AFK %ld %s>%s", ts.GetTotalSeconds (), (LPCTSTR) strArgument, ENDLINE ); SendPacket (strAFK, strAFK.GetLength ()); // send AFK info back MXP_error (DBG_INFO, infoMXP_AFKSent, TFormat ("Sent AFK response: %s" , (LPCTSTR) strAFK.Mid (4))); } // end of AFK break; case MXP_ACTION_SUPPORT: { CString strSupports; CAtomicElement * pElement; CStringList list; CString strName; if (ArgumentList.IsEmpty ()) { for (POSITION pos = App.m_ElementMap.GetStartPosition(); pos; ) { App.m_ElementMap.GetNextAssoc (pos, strName, pElement); if ((pElement->iFlags & TAG_NOT_IMP) == 0) { strSupports += "+"; strSupports += pElement->strName; strSupports += " "; // now list the sub-items it supports StringToList (pElement->strArgs, ",", list); // break into components for (POSITION argpos = list.GetHeadPosition (); argpos; ) { CString strItem = list.GetNext (argpos); // get argument item strSupports += "+"; strSupports += pElement->strName; strSupports += "."; strSupports += strItem; strSupports += " "; } // end of doing each sub-item } // end of being implemented } // end of looping through all atomic elements } // end of wanting complete list else { for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); CStringList questionlist; StringToList (pArgument->strValue, ".", questionlist); // break into components // should be one or two words, eg. send.prompt or color if (questionlist.GetCount () > 2) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) pArgument->strValue)); return; } CString strTag = questionlist.RemoveHead (); strTag.MakeLower (); // check valid name requested if (!IsValidName (strTag)) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) strTag)); return; } // look up main element name if (!App.m_ElementMap.Lookup (strTag, pElement) || (pElement->iFlags & TAG_NOT_IMP) != 0) { // not supported strSupports += "-"; strSupports += strTag; strSupports += " "; continue; // all done for this argument } // only one word - they aren't looking for a suboption if (questionlist.IsEmpty ()) { // supported strSupports += "+"; strSupports += strTag; strSupports += " "; continue; // all done for this argument } CString strSubtag = questionlist.RemoveHead (); strSubtag.MakeLower (); if (strSubtag == "*") { // they want list of options for this tag // now list the sub-items it supports StringToList (pElement->strArgs, ",", list); // break into components for (POSITION argpos = list.GetHeadPosition (); argpos; ) { CString strItem = list.GetNext (argpos); // get argument item strSupports += "+"; strSupports += pElement->strName; strSupports += "."; strSupports += strItem; strSupports += " "; } // end of doing each sub-item } // end of wildcard else { // not wildcard - must be name // check valid name requested if (!IsValidName (strSubtag)) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) strSubtag)); return; } // so, see if that word is in our arguments list StringToList (pElement->strArgs, ",", list); // break into components if (list.Find (strSubtag)) { strSupports += "+"; strSupports += pArgument->strValue; strSupports += " "; } else { strSupports += "-"; strSupports += pArgument->strValue; strSupports += " "; } } // end of not looking for wildcard } // end of doing each argument } // find individual items CString strMessage = CFormat ("\x1B[1z<SUPPORTS %s>%s", (LPCTSTR) strSupports, ENDLINE); SendPacket (strMessage, strMessage.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_SupportsSent, TFormat ("Sent supports response: %s" , (LPCTSTR) strMessage.Mid (4))); } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_SUPPORT case MXP_ACTION_OPTION: { CString strOptions; CStringList list; CString strName; if (ArgumentList.IsEmpty ()) { for (long i = 0; OptionsTable [i].pName; i++) { char * pName = OptionsTable [i].pName; strOptions += CFormat ("%s=%ld ", pName, (LPCTSTR) GetOptionItem (i)); } } // end of wanting complete list else { for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); strOptions += CFormat ("%s=%ld", (LPCTSTR) pArgument->strValue, (LPCTSTR) GetOption (pArgument->strValue)); } // end of doing each argument } // find individual items CString strMessage = CFormat ("\x1B[1z<OPTIONS %s>%s", (LPCTSTR) strOptions, ENDLINE); SendPacket (strMessage, strMessage.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_OptionsSent, TFormat ("Sent options response: %s" , (LPCTSTR) strMessage.Mid (4))); } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_OPTION case MXP_ACTION_RECOMMEND_OPTION: if (m_bMudCanChangeOptions) { CString strOptions; CStringList list; CString strName; for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); int iItem; int iResult = FindBaseOption (pArgument->strName, OptionsTable, iItem); if (iResult != eOK) MXP_error (DBG_ERROR, errMXP_InvalidOptionArgument, TFormat ("Option named '%s' not known.", (LPCTSTR) pArgument->strName)); else if (!(OptionsTable [iItem].iFlags & OPT_SERVER_CAN_WRITE)) MXP_error (DBG_ERROR, errMXP_CannotChangeOption, TFormat ("Option named '%s' cannot be changed.", (LPCTSTR) pArgument->strName)); else { iResult = SetOptionItem (iItem, atol (pArgument->strValue), true, false); if (iResult == eOK) MXP_error (DBG_INFO, infoMXP_OptionChanged, TFormat ("Option named '%s' changed to '%s'.", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue)); else MXP_error (DBG_ERROR, errMXP_OptionOutOfRange, TFormat ("Option named '%s' could not be changed to '%s' (out of range).", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue)); } } // end of doing each argument } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_RECOMMEND_OPTION case MXP_ACTION_USER: if (!m_name.IsEmpty () && m_connect_now == eConnectMXP) { CString strPacket = m_name + ENDLINE; SendPacket (strPacket, strPacket.GetLength ()); // send name to MUD MXP_error (DBG_INFO, infoMXP_CharacterNameSent, TFormat ("Sent character name: %s" , (LPCTSTR) m_name)); } else if (m_connect_now != eConnectMXP) MXP_error (DBG_WARNING, wrnMXP_CharacterNameRequestedButNotDefined, Translate ("Character name requested but auto-connect not set to MXP.")); else MXP_error (DBG_WARNING, wrnMXP_CharacterNameRequestedButNotDefined, Translate ("Character name requested but none defined.")); break; // end of USER case MXP_ACTION_PASSWORD: if (m_nTotalLinesSent > 10) // security check MXP_error (DBG_WARNING, wrnMXP_PasswordNotSent, "Too many lines sent to MUD - password not sent."); else if (!m_password.IsEmpty () && m_connect_now == eConnectMXP) { CString strPacket = m_password + ENDLINE; SendPacket (strPacket, strPacket.GetLength ()); // send password to MUD MXP_error (DBG_INFO, infoMXP_PasswordSent, "Sent password to world."); } else if (m_connect_now != eConnectMXP) MXP_error (DBG_WARNING, wrnMXP_PasswordRequestedButNotDefined, "Password requested but auto-connect not set to MXP."); else MXP_error (DBG_WARNING, wrnMXP_PasswordRequestedButNotDefined, "Password requested but none defined."); break; // end of PASSWORD // new para case MXP_ACTION_P: // experimental m_cLastChar = 0; m_bInParagraph = true; break; // end of MXP_ACTION_P // new line case MXP_ACTION_BR: bIgnoreUnusedArgs = true; // don't worry about args for now :) StartNewLine (true, 0); SetNewLineColour (0); break; // end of MXP_ACTION_BR // reset case MXP_ACTION_RESET: MXP_Off (); break; // end of MXP_ACTION_RESET // MXP options (MXP OFF, MXP DEFAULT_OPEN, MXP DEFAULT_SECURE etc. case MXP_ACTION_MXP: if (GetKeyword (ArgumentList, "off")) MXP_Off (true); /* if (GetKeyword (ArgumentList, "default_open")) { MXP_error (DBG_INFO, "MXP default mode now OPEN."); m_iMXP_defaultMode = eMXP_open; } // end of DEFAULT_OPEN if (GetKeyword (ArgumentList, "default_secure")) { MXP_error (DBG_INFO, "MXP default mode now SECURE."); m_iMXP_defaultMode = eMXP_secure; } // end of DEFAULT_SECURE if (GetKeyword (ArgumentList, "default_locked")) { MXP_error (DBG_INFO, "MXP default mode now LOCKED."); m_iMXP_defaultMode = eMXP_locked; } // end of DEFAULT_LOCKED if (GetKeyword (ArgumentList, "use_newlines")) { MXP_error (DBG_INFO, "Now interpreting newlines as normal."); m_bInParagraph = false; } // end of USE_NEWLINES if (GetKeyword (ArgumentList, "ignore_newlines")) { MXP_error (DBG_INFO, "Now ignoring newlines."); m_bInParagraph = true; } // end of IGNORE_NEWLINES */ break; // end of MXP_ACTION_MXP case MXP_ACTION_SCRIPT: MXP_error (DBG_INFO, infoMXP_ScriptCollectionStarted, "Script collection mode entered (discarding script)."); m_bMXP_script = true; break; // end of MXP_ACTION_SCRIPT case MXP_ACTION_HR: { // wrap up previous line if necessary if (m_pCurrentLine->len > 0) StartNewLine (true, 0); /* CString strLine; char * p = strLine.GetBuffer (m_nWrapColumn); memset (p, 175, m_nWrapColumn); strLine.ReleaseBuffer (m_nWrapColumn); AddToLine (strLine, 0); */ // mark line as HR line m_pCurrentLine->flags = HORIZ_RULE; StartNewLine (true, 0); // now finish this line } break; // end of MXP_ACTION_HR case MXP_ACTION_PRE: m_bPreMode = true; break; // end of MXP_ACTION_PRE case MXP_ACTION_UL: m_iListMode = eUnorderedList; m_iListCount = 0; break; // end of MXP_ACTION_UL case MXP_ACTION_OL: m_iListMode = eOrderedList; m_iListCount = 0; break; // end of MXP_ACTION_OL case MXP_ACTION_LI: { // wrap up previous line if necessary if (m_pCurrentLine->len > 0) StartNewLine (true, 0); CString strListItem = " * "; if (m_iListMode == eOrderedList) strListItem.Format (" %i. ", ++m_iListCount); AddToLine (strListItem, 0); } break; // end of MXP_ACTION_LI // pueblo tags we put here so we don't get warnings case MXP_ACTION_BODY : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_HEAD : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_HTML : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_TITLE: bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_SAMP : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_CENTER : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_XCH_PANE : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_IMG : case MXP_ACTION_IMAGE: { GetKeyword (ArgumentList, "ismap"); // make sure we realise it is a keyword // detect newline treatment strArgument = GetArgument (ArgumentList,"xch_mode", 0, false); // get mode if (!strArgument.IsEmpty ()) { m_bPuebloActive = true; // for correct newline processing if (strArgument.CompareNoCase ("purehtml") == 0) m_bSuppressNewline = true; else if (strArgument.CompareNoCase ("html") == 0) m_bSuppressNewline = false; } // end of some sort of Pueblo strArgument = GetArgument (ArgumentList,"url", 0, false); // get link if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"src", 0, false); // get link CString strFilename = GetArgument (ArgumentList,"fname", 0, false); // and file name if (!strArgument.IsEmpty ()) { CString strOldAction = strAction; int iFlags = pStyle->iFlags; COLORREF iForeColour = pStyle->iForeColour; COLORREF iBackColour = pStyle->iBackColour; // ensure on new line if (m_pCurrentLine->len > 0) StartNewLine (true, 0); // starting a new line may have deleted pStyle pStyle = m_pCurrentLine->styleList.GetTail (); if (m_bUseCustomLinkColour) { pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } strArgument += strFilename; // append filename to URL strAction = strArgument; // hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions pStyle->iFlags |= ACTION_HYPERLINK; // send-to action if (m_bUnderlineHyperlinks) pStyle->iFlags |= UNDERLINE; // send-to action AddToLine ("[", 0); AddToLine (strArgument, 0); AddToLine ("]", 0); // have to add the action now, before we start a new line pStyle->pAction = GetAction (strAction, strHint, strVariable); strAction.Empty (); StartNewLine (true, 0); // new line after image tag // go back to old style (ie. lose the underlining) AddStyle (iFlags, iForeColour, iBackColour, 0, strOldAction); } } break; // end of MXP_ACTION_IMG case MXP_ACTION_XCH_PAGE: bIgnoreUnusedArgs = true; m_bPuebloActive = true; // for correct newline processing MXP_Off (); // same as <reset>? break; // end of MXP_ACTION_XCH_PAGE case MXP_ACTION_VAR: // set variable strVariable = GetArgument (ArgumentList,"", 1, false); // get name // case insensitive strVariable.MakeLower (); if (!IsValidName (strVariable)) { MXP_error (DBG_ERROR, errMXP_InvalidDefinition, TFormat ("Invalid MXP entity name: <!%s>", (LPCTSTR) strVariable)); strVariable.Empty (); return; } { // protect local variable CString strEntityContents; if (App.m_EntityMap.Lookup (strVariable, strEntityContents)) { MXP_error (DBG_ERROR, errMXP_CannotRedefineEntity, TFormat ("Cannot redefine entity: &%s;", (LPCTSTR) strVariable)); strVariable.Empty (); return; } } break; // end of MXP_ACTION_VAR default: { // warn them it is not implemented MXP_error (DBG_WARNING, wrnMXP_TagNotImplemented, TFormat ("MXP tag <%s> is not implemented" , (LPCTSTR) strTag)); } // end of default } // end of switch on iAction if (!bIgnoreUnusedArgs) CheckArgumentsUsed (strTag, ArgumentList); } // end of CMUSHclientDoc::MXP_OpenAtomicTag
void CUser::NewCharToAgent(char *pBuf) { int index = 0, idlen = 0, send_index = 0, retvalue = 0; int charindex = 0, race = 0, Class = 0, hair = 0, face = 0, str = 0, sta = 0, dex = 0, intel = 0, cha = 0; char charid[MAX_ID_SIZE+1]; memset( charid, NULL, MAX_ID_SIZE+1 ); char send_buff[256]; memset( send_buff, NULL, 256); BYTE result; int sum = 0; _CLASS_COEFFICIENT* p_TableCoefficient = NULL; charindex = GetByte( pBuf, index ); if (!GetKOString(pBuf, charid, index, MAX_ID_SIZE)) { result = 0x05; goto fail_return; } race = GetByte( pBuf, index ); Class = GetShort( pBuf, index ); face = GetByte( pBuf, index ); hair = GetDWORD( pBuf, index ); str = GetByte( pBuf, index ); sta = GetByte( pBuf, index ); dex = GetByte( pBuf, index ); intel = GetByte( pBuf, index ); cha = GetByte( pBuf, index ); if( charindex > 4 || charindex < 0 ) { result = 0x01; goto fail_return; } if( !IsValidName( charid ) ) { result = 0x05; goto fail_return; } p_TableCoefficient = m_pMain->m_CoefficientArray.GetData( Class ); if( !p_TableCoefficient ) { result = 0x02; goto fail_return; } sum = str + sta + dex + intel + cha; if( sum > 300 ) { result = 0x02; goto fail_return; } if (str < 50 || sta < 50 || dex < 50 || intel < 50 || cha < 50) { result = 0x11; goto fail_return; } SetByte( send_buff, WIZ_NEW_CHAR, send_index ); SetShort( send_buff, m_Sid, send_index ); SetKOString( send_buff, m_strAccountID, send_index ); SetByte( send_buff, charindex, send_index ); SetKOString(send_buff, charid, send_index); SetByte( send_buff, race, send_index ); SetShort( send_buff, Class, send_index ); SetByte( send_buff, face, send_index ); SetDWORD( send_buff, hair, send_index ); SetByte( send_buff, str, send_index ); SetByte( send_buff, sta, send_index ); SetByte( send_buff, dex, send_index ); SetByte( send_buff, intel, send_index ); SetByte( send_buff, cha, send_index ); retvalue = m_pMain->m_LoggerSendQueue.PutData( send_buff, send_index ); if (retvalue < SMQ_FULL) return; DEBUG_LOG("NewChar Send Fail : %d", retvalue); fail_return: send_index = 0; SetByte( send_buff, WIZ_NEW_CHAR, send_index ); SetByte( send_buff, result, send_index ); Send( send_buff, send_index ); }
// here for start tag, eg. <bold> <underline> <usertag> void CMUSHclientDoc::MXP_StartTag (CString strTag) { // are we in secure mode right now? bool bSecure = MXP_Secure (); bool bNoReset = false; MXP_Restore_Mode (); // cancel secure-once mode static CArgumentList ArgumentList; CString strName; GetWord (strName, strTag); // count them m_iMXPtags++; if (!IsValidName (strName)) { MXP_error (DBG_ERROR, errMXP_InvalidElementName, TFormat ("Invalid MXP element name \"%s\" supplied.", strName)); return; } // case insensitive? strName.MakeLower (); // see if we know of this element CAtomicElement * pAtomicElement = NULL; CElement * pElement = NULL; bool bOpen; bool bCommand; POSITION atompos; // find existing styles CStyle * pStyle = m_pCurrentLine->styleList.GetTail (); unsigned short iFlags = pStyle->iFlags; COLORREF iForeColour = pStyle->iForeColour; COLORREF iBackColour = pStyle->iBackColour; CAction * pAction = pStyle->pAction; CString strAction; CString strHint; CString strVariable; // get old action, hint etc. so that something like: // <send href="nick"> <b> blah </b> </send> will work // in this case we want the href (action) to persist through the <b> if (pAction) { strAction = pAction->m_strAction; strHint = pAction->m_strHint; strVariable = pAction->m_strVariable; } // end of having an action etc. if (App.m_ElementMap.Lookup (strName, pAtomicElement)) { bOpen = (pAtomicElement->iFlags & TAG_OPEN) != 0; bCommand = (pAtomicElement->iFlags & TAG_COMMAND) != 0; bNoReset = (pAtomicElement->iFlags & TAG_NO_RESET) != 0; // check for mixing Pueblo and MXP tags /* // ALLOW BOTH for now if ((pAtomicElement->iFlags & TAG_PUEBLO) && !m_bPuebloActive) { MXP_error (DBG_ERROR, errMXP_PuebloOnly, TFormat ("Using Pueblo-only element in MXP mode: <%s>" , (LPCTSTR) strName)); return; } if ((pAtomicElement->iFlags & TAG_MXP) && m_bPuebloActive) { MXP_error (DBG_ERROR, errMXP_MXPOnly, TFormat ("Using MXP-only element in Pueblo mode: <%s>" , (LPCTSTR) strName)); return; } */ } // end of atomic element found else { if (!m_CustomElementMap.Lookup (strName, pElement)) { MXP_error (DBG_ERROR, errMXP_UnknownElement, TFormat ("Unknown MXP element: <%s>" , (LPCTSTR) strName)); return; } pAtomicElement = NULL; bOpen = pElement->bOpen; bCommand = pElement->bCommand; if (!pElement->strFlag.IsEmpty ()) strVariable = pElement->strFlag; // might have a variable to set } // end of not atomic // check for secure tags if (!bOpen && !bSecure && SECURE_ELEMENT_CHECK) { MXP_error (DBG_ERROR, errMXP_ElementWhenNotSecure, TFormat ("Secure MXP tag ignored when not in secure mode: <%s>" , (LPCTSTR) strName)); return; } if (BuildArgumentList (ArgumentList, strTag)) { DELETE_LIST (ArgumentList); return; } // call script if required for user-defined elements // atomic elements have their script called in MXP_OpenAtomicTag if ((m_dispidOnMXP_OpenTag != DISPID_UNKNOWN || m_bPluginProcessesOpenTag) && pAtomicElement == NULL) { bool bNotWanted = MXP_StartTagScript (strName, strTag, ArgumentList); // re-get current style in case the script did a world.note pStyle = m_pCurrentLine->styleList.GetTail (); // put things backt to how they were pStyle->iFlags = iFlags; pStyle->iForeColour = iForeColour; pStyle->iBackColour = iBackColour; if (bNotWanted) return; // they didn't want to go ahead with this tag } // If existing run is zero length, get rid of it, unless it // is a tag marker if (pStyle->iLength == 0 && (pStyle->iFlags & START_TAG) == 0) { DELETESTYLE (pStyle); m_pCurrentLine->styleList.RemoveTail (); } // command tags are not popped from the stack, and thus don't need a record if (!bCommand) { // add a marker to the current line for the tag itself // this is a record of what the text style was at this point AddStyle (iFlags | START_TAG, iForeColour, iBackColour, 0, strName, "", strVariable); // remember what is outstanding CActiveTag * pTag = new CActiveTag; pTag->strName = strName; pTag->bSecure = bSecure; pTag->bNoReset = bNoReset; m_ActiveTagList.AddTail (pTag); // add to outstanding tag list // warn if they are overdoing the outstanding tags if (m_ActiveTagList.GetCount () % OUTSTANDING_TAG_WARNING == 0 && m_ActiveTagList.GetCount () != m_iLastOutstandingTagCount) { MXP_error (DBG_WARNING, wrnMXP_ManyOutstandingTags, TFormat ( "Now have %i outstanding MXP tags" , m_ActiveTagList.GetCount ())); m_iLastOutstandingTagCount = m_ActiveTagList.GetCount (); } } // end of not command tag //if (strName == "ex") /* { iFlags &= ~COLOURTYPE; // clear bits, eg. custom iFlags |= COLOUR_RGB; iForeColour = 255; iBackColour = 255 * 256; } */ // now add another style entry to the line - this will have the // style adjusted for the new attributes (eg. bold) CStyle * pNewStyle = AddStyle (iFlags & STYLE_BITS, iForeColour, iBackColour, 0, NULL); // we will add the action later // atomic element? (looked-up earlier) if (pAtomicElement) { CArgument * pArgument; for (atompos = ArgumentList.GetHeadPosition (); atompos; ) { pArgument = ArgumentList.GetNext (atompos); // Walk the value for &xxx; entries if (pArgument->strValue.Find ('&') != -1) { const char * p = pArgument->strValue; const char * pStart = pArgument->strValue; CString strEntity; CString strFixedValue; strFixedValue.Empty (); long length; for ( ; *p; p++) { if (*p == '&') { // copy up to ampersand length = p - pStart; if (length > 0) strFixedValue += CString (pStart, length); p++; // skip ampersand pStart = p; // where entity starts for ( ; *p && *p != ';'; p++) // look for closing semicolon ; // just keep looking if (*p != ';') { MXP_error (DBG_ERROR, errMXP_NoClosingSemicolonInArgument, TFormat ("No closing \";\" in MXP element argument \"%s\"", (LPCTSTR) pArgument->strValue)); return; } strEntity = CString (pStart, p - pStart); // build entity, excluding & and ; // b. i. Look up entity in attribute list by name (eg. "col") CString strReplacement = "&text;"; if (strEntity != "text") strReplacement = MXP_GetEntity (strEntity); strFixedValue += strReplacement; // add to list pStart = p + 1; // move on past the entity } // end of having an ampersand } // end of processing the value strFixedValue += pStart; pArgument->strValue = strFixedValue; } // end of subsitution needed } // end of processing each argument in the atomic list MXP_OpenAtomicTag (strName, pAtomicElement->iAction, pNewStyle, strAction, strHint, strVariable, ArgumentList); // new style might have changed if they started a new line // (eg. BR) if (!m_pCurrentLine->styleList.IsEmpty ()) { pNewStyle = m_pCurrentLine->styleList.GetTail (); RememberStyle (pNewStyle); if (pNewStyle->pAction) { strAction = pNewStyle->pAction->m_strAction; strHint = pNewStyle->pAction->m_strHint; strVariable = pNewStyle->pAction->m_strVariable; } } pNewStyle->pAction = GetAction (strAction, strHint, strVariable); DELETE_LIST (ArgumentList); // clean up memory return; } // --------- end of processing for ATOMIC element ------------ // must be a user-defined element CElementItem * pElementItem; for (POSITION pos = pElement->ElementItemList.GetHeadPosition (); pos; ) { pElementItem = pElement->ElementItemList.GetNext (pos); CArgumentList BuiltArgumentList; BuiltArgumentList.RemoveAll (); /* we need to build up the arguments to the atomic element from 3 places: 1. The atom itself needs an argument list (eg. <COLOR &col;> ) 2. The user-defined element has an attribute list that lists possible arguments possibly with defaults, eg. col=red 3. The tag itself may supply values, eg. col=blue These are: 1. pElementItem->ArgumentList - what the atomic element wants 2. pElement->AttributeList - what it can get, including defaults 3. ArgumentList - what is specified on *this* tag So, I think we need to: a. Walk the atomic item's argument list b. For any entries in the form &xxx; ... 0. The special case &text; is left alone (for processing later) i. Look up the entity in the attribute list (2) above. ii. If found, go to (c). iii. Look up entity in entities map (could be < for instance) iv. If found, just replace it and continue v. If not found still, error c. If entity is found in attribute list (2) above, then: d. Look up value in supplied arguments (3) by name and position. e. If found, take supplied value. f. If not found, take default from (2) including <nothing> if applicable. Each entry gets built into BuiltArgumentList and passed down to the atomic element processing routine. */ // a. Walk the atom's list CArgument * pArgument; int iArgumentNumber = 0; for (atompos = pElementItem->ArgumentList.GetHeadPosition (); atompos; ) { pArgument = pElementItem->ArgumentList.GetNext (atompos); // b. Walk the value for &xxx; entries const char * p = pArgument->strValue; const char * pStart = pArgument->strValue; CString strEntity; CString strFixedValue; long length; strFixedValue.Empty (); for ( ; *p; p++) { if (*p == '&') { // copy up to ampersand length = p - pStart; if (length > 0) strFixedValue += CString (pStart, length); p++; // skip ampersand pStart = p; // where entity starts for ( ; *p && *p != ';'; p++) // look for closing semicolon ; // just keep looking if (*p != ';') { MXP_error (DBG_ERROR, errMXP_NoClosingSemicolonInArgument, TFormat ("No closing \";\" in MXP element argument \"%s\"", (LPCTSTR) pArgument->strValue)); return; } strEntity = CString (pStart, p - pStart); // build entity, excluding & and ; // b. i. Look up entity in attribute list by name (eg. "col") CString strReplacement = "&text;"; if (strEntity != "text") { CString strDefault; CArgument * pAttribute = NULL; int iSequence = 1; for (POSITION attpos = pElement->AttributeList.GetHeadPosition (); attpos; iSequence++) { pAttribute = pElement->AttributeList.GetNext (attpos); if (pAttribute->strName.IsEmpty ()) // no name, value is name (ie. no default) { if (pAttribute->strValue.CompareNoCase (strEntity) == 0) break; } else if (pAttribute->strName.CompareNoCase (strEntity) == 0) { strDefault = pAttribute->strValue; break; } pAttribute = NULL; // indicates it wasn't found } // end of looking for the attribute if (pAttribute) { // we now have a default and a position - look it up in the supplied arguments strReplacement = GetArgument (ArgumentList, strEntity, iSequence, false); if (strReplacement.IsEmpty ()) // empty? take default { strReplacement = strDefault; // stil empty? Warn them. if (strReplacement.IsEmpty ()) MXP_error (DBG_WARNING, wrnMXP_ArgumentNotSupplied, TFormat ("Non-default argument \"%s\" not supplied to <%s>", (LPCTSTR) strEntity, (LPCTSTR) strName )); } } // end of attribute found else strReplacement = MXP_GetEntity (strEntity); } // end of not being the entity &text; strFixedValue += strReplacement; // add to list pStart = p + 1; // move on past the entity } // end of having an ampersand } // end of processing the value strFixedValue += pStart; // add fixed argument to the built argument list CArgument * pNewArgument; if (pArgument->strName.IsEmpty ()) // just a positional argument { pNewArgument = new CArgument ("", strFixedValue, ++iArgumentNumber); BuiltArgumentList.AddTail (pNewArgument); } else { pNewArgument = new CArgument (pArgument->strName, strFixedValue, 0); BuiltArgumentList.AddTail (pNewArgument); } } // end of processing each argument in the atomic list MXP_OpenAtomicTag (pElementItem->pAtomicElement->strName, pElementItem->pAtomicElement->iAction, pNewStyle, strAction, strHint, strVariable, BuiltArgumentList); DELETE_LIST (BuiltArgumentList); // just a temporary list } // end of doing each atomic element // new style might have changed if they started a new line // (eg. BR) if (!m_pCurrentLine->styleList.IsEmpty ()) { pNewStyle = m_pCurrentLine->styleList.GetTail (); RememberStyle (pNewStyle); } // make an action for the built-up action/hint/variable pNewStyle->pAction = GetAction (strAction, strHint, strVariable); // check all arguments used CheckArgumentsUsed (strName, ArgumentList); DELETE_LIST (ArgumentList); // clean up memory } // end of CMUSHclientDoc::MXP_StartTag
//---------------------------------------------------------------------------- bool SceneBuilder::ConvertColorAttrib(IParamBlock2 *paramBlock, int index, std::string &name, PX2::Float4 &color, int &increment) { ParamBlockDesc2 *paramDesc = paramBlock->GetDesc(); int numParams = paramBlock->NumParams(); if (!paramDesc) return false; ParamDef &colorParamDef = paramDesc->GetParamDef( paramDesc->IndextoID(index)); ParamDef &alphaParamDef = paramDesc->GetParamDef( paramDesc->IndextoID(index+1)); Color colorValue; float alphaValue = 255.0f; Interval validInterval; BOOL retrievedColor = false; BOOL retrievedAlpha = false; int alphaIndex = index + 1; retrievedColor = paramBlock->GetValue((ParamID)index, 0, colorValue, validInterval); if (alphaIndex < numParams) { int param_type = paramBlock->GetParameterType((ParamID)alphaIndex); if (param_type == TYPE_FLOAT) { retrievedAlpha = paramBlock->GetValue((ParamID)alphaIndex, 0, alphaValue, validInterval); } } if (retrievedColor) { char* valueName = colorParamDef.int_name; if (!IsValidName(valueName)) { valueName = paramBlock->GetLocalName((ParamID)index); } assertion(IsValidName(valueName), "valueName must be valuable."); name = std::string(valueName); Control *colorControl = paramBlock->GetController(index, 0); PX2_UNUSED(colorControl); bool hasAlpha = false; Control *alphaControl = 0; if (retrievedAlpha) { TCHAR *valueAlphaName = alphaParamDef.int_name; if (!IsValidName(valueAlphaName)) valueName = paramBlock->GetLocalName((ParamID)alphaIndex); assertion(IsValidName(valueAlphaName), "valueName must be valuable."); alphaControl = paramBlock->GetController(alphaIndex, 0); std::string strColorName = valueName; strColorName += "Alpha"; if (!strcmp(strColorName.c_str(), valueAlphaName)) { hasAlpha = true; increment++; } else { alphaControl = 0; } } if (hasAlpha) { color = PX2::Float4(colorValue.r, colorValue.g, colorValue.b, alphaValue); } else { color = PX2::Float4(colorValue.r, colorValue.g, colorValue.b, 1.0f); } } return true; }
/** Add new section item into Section head. @param[in] Buffer Section item data buffer. @param[in] BufferSize Size of section item. @param[in, out] SectionHead Section item head entry. @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. @retval EFI_SUCCESS Section item is NULL or Section item is added. **/ EFI_STATUS ProfileGetSection ( IN UINT8 *Buffer, IN UINTN BufferSize, IN OUT SECTION_ITEM **SectionHead ) { SECTION_ITEM *SectionItem; UINTN Length; UINT8 *PtrBuf; UINT8 *PtrEnd; ASSERT(BufferSize >= 1); // // The first character of Buffer is '[', now we want for ']' // PtrEnd = (UINT8 *)((UINTN)Buffer + BufferSize - 1); PtrBuf = (UINT8 *)((UINTN)Buffer + 1); while (PtrBuf <= PtrEnd) { if (*PtrBuf == ']') { break; } PtrBuf ++; } if (PtrBuf > PtrEnd) { // // Not found. Invalid line // return EFI_NOT_FOUND; } if (PtrBuf <= Buffer + 1) { // Empty name return EFI_NOT_FOUND; } // // excluding the heading '[' and tailing ']' // Length = PtrBuf - Buffer - 1; ProfileTrim ( Buffer + 1, &Length ); // // Invalid line if the section name is null // if (Length == 0) { return EFI_NOT_FOUND; } if (!IsValidName((CHAR8 *)Buffer + 1, Length)) { return EFI_INVALID_PARAMETER; } SectionItem = AllocatePool (sizeof (SECTION_ITEM)); if (SectionItem == NULL) { return EFI_OUT_OF_RESOURCES; } SectionItem->PtrSection = NULL; SectionItem->SecNameLen = Length; SectionItem->PtrEntry = NULL; SectionItem->PtrValue = NULL; SectionItem->PtrNext = *SectionHead; *SectionHead = SectionItem; // // Add a trailing '\0' // SectionItem->PtrSection = AllocatePool (Length + 1); if (SectionItem->PtrSection == NULL) { return EFI_OUT_OF_RESOURCES; } // // excluding the heading '[' // CopyMem (SectionItem->PtrSection, Buffer + 1, Length); *(SectionItem->PtrSection + Length) = '\0'; return EFI_SUCCESS; }
/** Add new section entry and entry value into Section head. @param[in] Buffer Section entry data buffer. @param[in] BufferSize Size of section entry. @param[in, out] SectionHead Section item head entry. @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. @retval EFI_SUCCESS Section entry is added. @retval EFI_NOT_FOUND Section entry is not found. @retval EFI_INVALID_PARAMETER Section entry is invalid. **/ EFI_STATUS ProfileGetEntry ( IN UINT8 *Buffer, IN UINTN BufferSize, IN OUT SECTION_ITEM **SectionHead ) { EFI_STATUS Status; SECTION_ITEM *SectionItem; SECTION_ITEM *PtrSection; UINTN Length; UINT8 *PtrBuf; UINT8 *PtrEnd; Status = EFI_SUCCESS; PtrBuf = Buffer; PtrEnd = (UINT8 *) ((UINTN)Buffer + BufferSize - 1); // // First search for '=' // while (PtrBuf <= PtrEnd) { if (*PtrBuf == '=') { break; } PtrBuf++; } if (PtrBuf > PtrEnd) { // // Not found. Invalid line // return EFI_NOT_FOUND; } if (PtrBuf <= Buffer) { // Empty name return EFI_NOT_FOUND; } // // excluding the tailing '=' // Length = PtrBuf - Buffer; ProfileTrim ( Buffer, &Length ); // // Invalid line if the entry name is null // if (Length == 0) { return EFI_NOT_FOUND; } if (!IsValidName((CHAR8 *)Buffer, Length)) { return EFI_INVALID_PARAMETER; } // // Omit this line if no section header has been found before // if (*SectionHead == NULL) { return Status; } PtrSection = *SectionHead; SectionItem = AllocatePool (sizeof (SECTION_ITEM)); if (SectionItem == NULL) { return EFI_OUT_OF_RESOURCES; } SectionItem->PtrSection = NULL; SectionItem->PtrEntry = NULL; SectionItem->PtrValue = NULL; SectionItem->SecNameLen = PtrSection->SecNameLen; SectionItem->PtrNext = *SectionHead; *SectionHead = SectionItem; // // SectionName, add a trailing '\0' // SectionItem->PtrSection = AllocatePool (PtrSection->SecNameLen + 1); if (SectionItem->PtrSection == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (SectionItem->PtrSection, PtrSection->PtrSection, PtrSection->SecNameLen + 1); // // EntryName, add a trailing '\0' // SectionItem->PtrEntry = AllocatePool (Length + 1); if (SectionItem->PtrEntry == NULL) { FreePool(SectionItem->PtrSection); return EFI_OUT_OF_RESOURCES; } CopyMem (SectionItem->PtrEntry, Buffer, Length); *(SectionItem->PtrEntry + Length) = '\0'; // // Next search for '#' or ';' // PtrBuf = PtrBuf + 1; Buffer = PtrBuf; while (PtrBuf <= PtrEnd) { if (*PtrBuf == '#' || *PtrBuf == ';') { break; } PtrBuf++; } if (PtrBuf <= Buffer) { // Empty name FreePool(SectionItem->PtrEntry); FreePool(SectionItem->PtrSection); return EFI_NOT_FOUND; } Length = PtrBuf - Buffer; ProfileTrim ( Buffer, &Length ); // // Invalid line if the entry value is null // if (Length == 0) { FreePool(SectionItem->PtrEntry); FreePool(SectionItem->PtrSection); return EFI_NOT_FOUND; } if (!IsValidValue((CHAR8 *)Buffer, Length)) { FreePool(SectionItem->PtrEntry); FreePool(SectionItem->PtrSection); return EFI_INVALID_PARAMETER; } // // EntryValue, add a trailing '\0' // SectionItem->PtrValue = AllocatePool (Length + 1); if (SectionItem->PtrValue == NULL) { FreePool(SectionItem->PtrEntry); FreePool(SectionItem->PtrSection); return EFI_OUT_OF_RESOURCES; } CopyMem (SectionItem->PtrValue, Buffer, Length); *(SectionItem->PtrValue + Length) = '\0'; return EFI_SUCCESS; }
void CMUSHclientDoc::MXP_EndTag (CString strTag) { bool bSecure = MXP_Secure () ; MXP_Restore_Mode (); // cancel secure-once mode CString strName; GetWord (strName, strTag); if (!IsValidName (strName)) { MXP_error (DBG_ERROR, errMXP_InvalidElementName, TFormat ("Invalid MXP tag name: </%s>", (LPCTSTR) m_strMXPstring)); return; } strName.MakeLower (); // case insensitive // should just have tag name, not </tag blah blah> if (!strTag.IsEmpty ()) MXP_error (DBG_WARNING, wrnMXP_ArgumentsToClosingTag, TFormat ("Closing MXP tag </%s %s> has inappropriate arguments", (LPCTSTR) strName, (LPCTSTR) strTag)); // make sure tag is in active taglist // eg. </unknown> will not close any open tags // this test effectively checks that tag is known (otherwise it won't be in the list) CActiveTag * pTag = NULL; for (POSITION pos = m_ActiveTagList.GetTailPosition (); pos; ) { pTag = m_ActiveTagList.GetPrev (pos); if (pTag->strName == strName) break; else { // check we don't cross over some secure tags when finding it if (!bSecure && pTag->bSecure) { MXP_error (DBG_WARNING, wrnMXP_OpenTagBlockedBySecureTag, TFormat ("Cannot close open MXP tag <%s> " "- blocked by secure tag <%s>", (LPCTSTR) strName, (LPCTSTR) pTag->strName)); return; } pTag = NULL; } } // end of doing each one if (!pTag) { MXP_error (DBG_WARNING, wrnMXP_OpenTagNotThere, TFormat ("Closing MXP tag </%s> does not have corresponding opening tag", (LPCTSTR) strName)); return; } if (!bSecure && pTag->bSecure) { MXP_error (DBG_WARNING, wrnMXP_TagOpenedInSecureMode, TFormat ("Cannot close open MXP tag <%s> " "- it was opened in secure mode.", (LPCTSTR) strName)); return; } // we know it is in the list - close all tags until we reach this one // eg. <b> <i> </b> </i> // in the above example the </b> will also close the <i> while (true) { pTag = m_ActiveTagList.RemoveTail (); CString strTag = pTag->strName; delete pTag; if (strTag != strName) MXP_error (DBG_WARNING, wrnMXP_ClosingOutOfSequenceTag, TFormat ("Closing out-of-sequence MXP tag: <%s>", (LPCTSTR) strTag)); MXP_CloseTag (strTag); if (strTag == strName) break; // stop once we have found the tag we are supposed to close } } // end of CMUSHclientDoc::MXP_EndTag