std::vector<std::string> InfoManager::GetLoadingAnnouncments() { STRINGLIST l = g_ClusterManager.GetList(LISTPREFIX_LOADING_ANNOUNCMENTS); STRINGLIST s; if(l.size() == 0) { s.push_back(StringUtil::Format(ReplaceBrandingPatterns("Welcome to ${GameName} - ${Edition}. You can set your own <b>Loading Announcements</b> by creating and adding multiple elements to the list <b>'%s'</b> in the Redis database."), LISTPREFIX_LOADING_ANNOUNCMENTS.c_str())); } else { for(auto it = l.begin(); it != l.end(); ++it) { s.push_back(ReplaceBrandingPatterns(*it)); } } return s; }
void IGFManager :: GetCategory(int id, MULTISTRING &output) { IGFCategory *category = GetPagedCategoryPtr(id); if(category == NULL) return; STRINGLIST header; header.push_back(ConvertInteger(id)); header.push_back(category->mTitle); output.push_back(header); EnumCategoryList(id, output); EnumThreadList(id, output); }
void AINutPlayer::PlaySound(const char *name) { STRINGLIST sub; Util::Split(name, "|", sub); while (sub.size() < 2) { sub.push_back(""); } attachedCreature->SendPlaySound(sub[0].c_str(), sub[1].c_str()); }
void IGFManager :: EnumCategoryList(int parentID, MULTISTRING &output) { STRINGLIST entry; CATEGORYPAGE::iterator it; IGFCategoryPage::CATEGORYENTRY::iterator eit; for(it = mCategoryPages.begin(); it != mCategoryPages.end(); ++it) { for(eit = it->second.mEntries.begin(); eit != it->second.mEntries.end(); ++eit) { if(eit->second.mParentCategory == parentID) { entry.push_back(ConvertInteger(TYPE_CATEGORY)); entry.push_back(ConvertInteger(eit->second.mID)); entry.push_back(ConvertInteger(eit->second.mLocked)); entry.push_back(ConvertInteger(0)); //Stickied. Categories don't have this. entry.push_back(eit->second.mTitle); entry.push_back(ConvertInteger(eit->second.mThreadList.size())); entry.push_back(ConvertInteger(GetTimeOffset(eit->second.mLastUpdateTime))); output.push_back(entry); entry.clear(); } } } }
// Tokenize a string using whitespace as separators, but including string quotations. void TokenizeByWhitespace(const std::string &input, STRINGLIST &output) { std::string str = input; output.clear(); size_t len = str.size(); int first = -1; int last = -1; bool quote = false; bool terminate = false; for(size_t i = 0; i < len; i++) { switch(input[i]) { case '"': terminate = true; //Treat opening quote as a block start quote = !quote; break; case ' ': case '\t': case '\n': case '\r': if(quote == false) terminate = true; break; default: if(first == -1) first = i; last = i; } if(terminate == true) { if(first >= 0 && last >= 0) { std::string t = str.substr(first, last - first + 1); output.push_back(str.substr(first, last - first + 1)); first = -1; last = -1; } terminate = false; } } if(first != -1 && first < (int)len) output.push_back(str.substr(first, len - first + 1)); }
void IGFManager :: OpenCategory(int type, int id, MULTISTRING &output) { //Expand an object. If it's a category, enumerate a list of subcategories. if(type == TYPE_CATEGORY) { IGFCategory *category = GetPagedCategoryPtr(id); if(category != NULL) { STRINGLIST header; header.push_back(ConvertInteger(id)); header.push_back(category->mTitle); output.push_back(header); int searchID = category->mID; EnumCategoryList(searchID, output); EnumThreadList(searchID, output); } } }
void IGFManager :: EnumThreadList(int parentID, MULTISTRING &output) { IGFCategory* category = GetPagedCategoryPtr(parentID); if(category == NULL) return; //Pregenerate a list of threads std::vector<IGFThread*> results; for(size_t i = 0; i < category->mThreadList.size(); i++) { IGFThread* thread = GetPagedThreadPtr(category->mThreadList[i]); if(thread != NULL) results.push_back(thread); } if(category->mFlags.hasFlag(IGFFlags::FLAG_SORTALPHABETICAL)) std::sort(results.begin(), results.end(), ThreadSortAlphabetical); STRINGLIST entry; for(size_t i = 0; i < results.size(); i++) { IGFThread* thread = results[i]; entry.push_back(ConvertInteger(TYPE_THREAD)); entry.push_back(ConvertInteger(thread->mID)); entry.push_back(ConvertInteger(thread->mLocked)); entry.push_back(ConvertInteger(thread->mStickied)); entry.push_back(thread->mTitle); entry.push_back(ConvertInteger(thread->mPostList.size())); entry.push_back(ConvertInteger(GetTimeOffset(thread->mLastUpdateTime))); output.push_back(entry); entry.clear(); } }
int QuestActionContainer :: ExecuteSingleCommand(SimulatorThread *caller, ExtendedQuestAction &e) { CreatureInstance *cInst = caller->creatureInst; switch(e.opCode) { case COMMAND_NONE: return 0; case CONDITION_HEROISM: { int value = cInst->css.heroism; if(Compare(value, e.param[0], e.param[1]) == true) return 0; caller->SendInfoMessage("You don't meet the heroism requirement.", INFOMSG_ERROR); return -1; } break; case CONDITION_HAS_ITEM: { int itemID = e.param[0]; int itemCount = e.param[1]; int count = caller->pld.charPtr->inventory.GetItemCount(INV_CONTAINER, itemID); if(count >= itemCount) return 0; caller->SendInfoMessage("You don't have the required items in your backpack inventory.", INFOMSG_ERROR); return -1; } break; case CONDITION_HAS_QUEST: { int questID = e.param[0]; if(caller->pld.charPtr->questJournal.activeQuests.HasQuestID(questID) > -1) return 0; return -1; } break; case CONDITION_BELOW_LEVEL: { int maxLevel = e.param[0]; if(caller->pld.charPtr->cdef.css.level < maxLevel) return 0; caller->SendInfoMessage("You are too high a level to accept this quest.", INFOMSG_ERROR); return -1; } break; case CONDITION_TRANSFORMED: { int creatureDefID = e.param[0]; if(cInst->IsTransformed() && cInst->transformCreatureId == creatureDefID) return 0; CreatureDefinition *def = CreatureDef.GetPointerByCDef(creatureDefID); char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), "You must be transformed into %s to continue with this quest.", def->css.display_name); caller->SendInfoMessage(buffer, INFOMSG_INFO); return -1; } case CONDITION_UNTRANSFORMED: { if(!cInst->IsTransformed()) return 0; CreatureDefinition *def = CreatureDef.GetPointerByCDef(cInst->transformCreatureId); char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), "You cannot be transformed into %s to continue with this quest.", def->css.display_name); caller->SendInfoMessage(buffer, INFOMSG_INFO); return -1; } break; case ACTION_CHANGE_HEROISM: cInst->css.heroism += e.param[0]; cInst->OnHeroismChange(); break; case ACTION_REMOVE_ITEM: { int itemID = e.param[0]; int itemCount = e.param[1]; char buffer[2048]; int len = caller->pld.charPtr->inventory.RemoveItemsAndUpdate(INV_CONTAINER, itemID, itemCount, buffer); if(len > 0) caller->AttemptSend(buffer, len); } break; case ACTION_SEND_TEXT: caller->SendInfoMessage(e.paramStr.c_str(), INFOMSG_INFO); break; case ACTION_PLAY_SOUND: { STRINGLIST sub; Util::Split(e.paramStr, "|", sub); while(sub.size() < 2) { sub.push_back(""); } caller->SendPlaySound(sub[0].c_str(), sub[1].c_str()); } break; case ACTION_BROADCAST: { char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), e.paramStr.c_str(), cInst->css.display_name); g_SimulatorManager.BroadcastMessage(buffer); } break; case ACTION_JOIN_GUILD: { int guildDefID = e.param[0]; GuildDefinition *gDef = g_GuildManager.GetGuildDefinition(guildDefID); if(gDef == NULL) caller->SendInfoMessage("Hrmph. This guild does not exist, please report a bug!", INFOMSG_INFO); else { caller->SendInfoMessage("Joining guild ..", INFOMSG_INFO); caller->JoinGuild(gDef, 0); char buffer[64]; Util::SafeFormat(buffer, sizeof(buffer), "You have joined %s", gDef->defName.c_str()); caller->SendInfoMessage(buffer, INFOMSG_INFO); } } break; case ACTION_TRANSFORM: { int creatureDefID = e.param[0]; g_Logs.data->debug("Transform: %v", creatureDefID); cInst->CAF_Transform(creatureDefID, 0, -1); } break; case ACTION_UNTRANSFORM: { g_Logs.data->debug("Untransform"); cInst->CAF_Untransform(); } break; default: return -1; } return 0; }
void IGFManager :: OpenThread(int threadID, int startPost, int requestedCount, MULTISTRING &output) { IGFThread *thread = GetPagedThreadPtr(threadID); if(thread == NULL) return; startPost = Util::ClipInt(startPost, 0, thread->mPostList.size() - 1); STRINGLIST row; //We retrieve the time offset since the first session since the client uses //4 byte integers which theoretically may not be large enough to hold the time data. unsigned long timeOffset = g_PlatformTime.getAbsoluteMinutes(); //Prepare the header row.push_back(ConvertInteger(threadID)); //[0] row.push_back(thread->mTitle); //[1] row.push_back(ConvertInteger(startPost)); //[2] row.push_back(ConvertInteger(thread->mPostList.size())); //[3] row.push_back(ConvertInteger(timeOffset - thread->mLastUpdateTime)); //[4] output.push_back(row); row.clear(); //Append the post data. int count = 0; for(size_t i = startPost; i < thread->mPostList.size(); i++) { IGFPost *post = GetPagedPostPtr(thread->mPostList[i]); if(post == NULL) { g_Logs.data->error("OpenThread: unable to find post: %v", thread->mPostList[i]); continue; } row.push_back(ConvertInteger(post->mID)); //[0] row.push_back(post->mCreatorName.c_str()); //[1] row.push_back(post->mCreationTime.c_str()); //[2] row.push_back(ConvertInteger(timeOffset - post->mPostedTime)); //[3] row.push_back(post->mBodyText.c_str()); //[4] row.push_back(ConvertInteger(post->mEditCount)); //[5] row.push_back(ConvertInteger(timeOffset - post->mLastUpdateTime)); //[6] output.push_back(row); row.clear(); if(++count >= requestedCount) break; } }
void AIScriptPlayer :: RunImplementationCommands(int opcode) { ScriptCore::OpData *in = &def->instr[curInst]; switch(opcode) { case OP_USE: if(attachedCreature->ab[0].bPending == false) { //DEBUG OUTPUT if(g_Config.DebugLogAIScriptUse == true) { const Ability2::AbilityEntry2* abptr = g_AbilityManager.GetAbilityPtrByID(in->param1); g_Logs.script->debug("Using: %v", abptr->GetRowAsCString(Ability2::ABROW::NAME)); } //END DEBUG OUTPUT int r = attachedCreature->CallAbilityEvent(in->param1, EventType::onRequest); if(r != 0) { //Notify the creature we failed, may need a distance check. //The script should wait and retry soon. attachedCreature->AICheckAbilityFailure(r); nextFire = g_ServerTime + USE_FAIL_DELAY; if(g_Config.DebugLogAIScriptUse == true) { const Ability2::AbilityEntry2* abptr = g_AbilityManager.GetAbilityPtrByID(in->param1); g_Logs.script->debug("Using: %v Failed: %v", abptr->GetRowAsCString(Ability2::ABROW::NAME), g_AbilityManager.GetAbilityErrorCode(r)); } if(attachedCreature->AIAbilityFailureAllowRetry(r) == true) { advance = 0; //Don't advance the instruction so that we can retry this command. } } } else { advance = 0; nextFire = g_ServerTime + USE_FAIL_DELAY; } break; case OP_GETWILL: SetVar(def->instr[curInst].param1, attachedCreature->css.will); break; case OP_GETWILLCHARGE: SetVar(def->instr[curInst].param1, attachedCreature->css.will_charges); break; case OP_GETMIGHT: SetVar(def->instr[curInst].param1, attachedCreature->css.might); break; case OP_GETMIGHTCHARGE: SetVar(def->instr[curInst].param1, attachedCreature->css.might_charges); break; case OP_HASTARGET: SetVar(def->instr[curInst].param1, (attachedCreature->CurrentTarget.targ != NULL) ? 1 : 0); break; case OP_GETLEVEL: SetVar(def->instr[curInst].param1, attachedCreature->css.level); break; case OP_DEBUGPRINT: g_Logs.script->debug("[DEBUGPRINT] (%v) %v", def->scriptName, def->stringList[def->instr[curInst].param1].c_str()); break; case OP_GETCOOLDOWN: { const char *cooldownName = GetStringTableEntry(def->instr[curInst].param1); int cooldownID = g_AbilityManager.ResolveCooldownCategoryID(cooldownName); int result = (attachedCreature->HasCooldown(cooldownID) == true) ? 1 : 0; SetVar(in->param2, result); } break; case OP_ISBUSY: { int result = (attachedCreature->AICheckIfAbilityBusy() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_COUNTENEMYNEAR: { float x = (float)attachedCreature->CurrentX; float z = (float)attachedCreature->CurrentZ; SetVar(in->param2, attachedCreature->AICountEnemyNear(in->param1, x, z)); } break; case OP_COUNTENEMYAT: { float x = (float)attachedCreature->CurrentX; float z = (float)attachedCreature->CurrentZ; if(attachedCreature->CurrentTarget.targ != NULL) { x = (float)attachedCreature->CurrentTarget.targ->CurrentX; z = (float)attachedCreature->CurrentTarget.targ->CurrentZ; } SetVar(in->param2, attachedCreature->AICountEnemyNear(in->param1, x, z)); } break; case OP_HEALTHPERCENT: SetVar(in->param1, static_cast<int>(attachedCreature->GetHealthRatio() * 100.0F)); break; case OP_TARGETHEALTHPERCENT: { int health = 0; if(attachedCreature->CurrentTarget.targ != NULL) health = static_cast<int>(attachedCreature->CurrentTarget.targ->GetHealthRatio() * 100.0F); SetVar(in->param1, health); } break; case OP_SETELAPSEDTIME: SetVar(in->param1, static_cast<int>(g_PlatformTime.getElapsedMilliseconds())); break; case OP_TIMEOFFSET: { unsigned long offset = g_PlatformTime.getElapsedMilliseconds() - static_cast<unsigned long>(GetVarValue(in->param1)); SetVar(in->param2, static_cast<int>(offset)); } break; case OP_VISUALEFFECT: attachedCreature->SendEffect(GetStringTableEntry(in->param1), 0); break; case OP_VISUALEFFECTT: { int targID = 0; if(attachedCreature->CurrentTarget.targ != NULL) targID = attachedCreature->CurrentTarget.targ->CreatureID; attachedCreature->SendEffect(GetStringTableEntry(in->param1), targID); } break; case OP_SAY: attachedCreature->SendSay(GetStringTableEntry(in->param1)); break; case OP_INSTANCECALL: attachedCreature->actInst->ScriptCall(GetStringTableEntry(in->param1)); break; case OP_GETIDLEMOB: { int creatureDefID = in->param1; int creatureID = attachedCreature->AIGetIdleMob(creatureDefID); SetVar(in->param2, creatureID); } break; case OP_GETTARGET: { int creatureID = 0; if(attachedCreature->CurrentTarget.targ != NULL) creatureID = attachedCreature->CurrentTarget.targ->CreatureID; SetVar(in->param1, creatureID); } break; case OP_GETSELF: SetVar(in->param1, attachedCreature->CreatureID); break; case OP_SETOTHERTARGET: { int creatureID = GetVarValue(in->param1); int creatureIDTarg = GetVarValue(in->param2); attachedCreature->AIOtherSetTarget(creatureID, creatureIDTarg); } break; case OP_AISCRIPTCALL: { int creatureID = GetVarValue(in->param1); attachedCreature->AIOtherCallLabel(creatureID, GetStringTableEntry(in->param2)); } break; case OP_ISTARGETENEMY: { int result = (attachedCreature->AIIsTargetEnemy() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_ISTARGETFRIENDLY: { int result = (attachedCreature->AIIsTargetFriend() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_SETSPEED: attachedCreature->Speed = in->param1; break; case OP_GETTARGETCDEF: { int targCDef = 0; if(attachedCreature->CurrentTarget.targ != NULL) targCDef = attachedCreature->CurrentTarget.targ->CreatureDefID; SetVar(in->param1, targCDef); } break; case OP_GETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); SetVar(in->param2, static_cast<int>(attachedCreature->AIGetProperty(propName, false))); } break; case OP_GETTARGETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); SetVar(in->param2, static_cast<int>(attachedCreature->AIGetProperty(propName, true))); } break; case OP_DISPELTARGETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); int sign = in->param2; attachedCreature->AIDispelTargetProperty(propName, sign); } break; case OP_RANDOMIZE: SetVar(in->param2, randint(1, in->param1)); break; case OP_FINDCDEF: { int creatureID = 0; CreatureInstance *targ = attachedCreature->actInst->GetNPCInstanceByCDefID(in->param1); if(targ != NULL) creatureID = targ->CreatureID; SetVar(in->param2, creatureID); } break; case OP_PLAYSOUND: { STRINGLIST sub; Util::Split(GetStringTableEntry(in->param1), "|", sub); while(sub.size() < 2) { sub.push_back(""); } attachedCreature->SendPlaySound(sub[0].c_str(), sub[1].c_str()); } break; case OP_GETBUFFTIER: SetVar(in->param2, attachedCreature->AIGetBuffTier(in->param1, false)); break; case OP_GETTARGETBUFFTIER: SetVar(in->param2, attachedCreature->AIGetBuffTier(in->param1, true)); break; case OP_TARGETINRANGE: SetVar(in->param2, (attachedCreature->InRange_Target((float)in->param1) == true) ? 1 : 0); break; case OP_GETTARGETRANGE: SetVar(in->param1, attachedCreature->AIGetTargetRange()); break; case OP_SETGTAE: attachedCreature->AISetGTAE(); break; case OP_GETSPEED: { int result = 0; int creatureID = GetVarValue(in->param1); CreatureInstance *targ = ResolveCreatureInstance(creatureID); if(targ != NULL) { result = targ->Speed; } SetVar(in->param2, result); } break; case OP_CIDISBUSY: { int result = 0; CreatureInstance *targ = ResolveCreatureInstance(GetVarValue(in->param1)); if(targ != NULL) { result = (targ->AICheckIfAbilityBusy() == true) ? 1 : 0; } SetVar(in->param2, result); } break; default: g_Logs.script->error("Unidentified op type: %v", in->opCode); break; } }
int TradeEssenceHandler::handleQuery(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { /* Query: trade.essence Sent when an item is purchased from a chest using tokens or essences, instead of gold. Args : [0] = Creature Instance ID [1] = Item proto of the player's selection. */ // [0] = Creature Instance ID // [1] = Item Proto that was selected ex: "item143548:0:0:0" if (query->argCount < 2) return 0; int CID = atoi(query->args[0].c_str()); int CDef = sim->ResolveCreatureDef(CID); //Since the Essence Shop scanning functions modify the string while searching //for tokens, copy it to a buffer here. Util::SafeCopy(sim->Aux1, query->args[1].c_str(), sizeof(sim->Aux1)); EssenceShopItem *iptr = NULL; EssenceShop *esptr = creatureInstance->actInst->essenceShopList.GetEssenceShopPtr(CDef, sim->Aux1, &iptr); if (esptr == NULL || iptr == NULL) { g_Logs.simulator->error( "[%d] Failed to process EssenceShop item [%s] for CreatureDef [%d]", sim->InternalID, sim->Aux1, CDef); return PrepExt_QueryResponseError(sim->SendBuf, query->ID, "Failed to determine item selection."); } InventoryManager &inv = pld->charPtr->inventory; int currentItemCount = inv.GetItemCount(INV_CONTAINER, esptr->EssenceID); if (currentItemCount < iptr->EssenceCost) { g_Logs.simulator->warn("[%v] Essence requirement for item %v: %v / %v", sim->InternalID, esptr->EssenceID, currentItemCount, iptr->EssenceCost); return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "You do not have enough essences."); } InventorySlot *newItem = pld->charPtr->inventory.AddItem_Ex(INV_CONTAINER, iptr->ItemID, 1); if (newItem == NULL) { pld->charPtr->pendingChanges++; int err = pld->charPtr->inventory.LastError; if (err == InventoryManager::ERROR_ITEM) return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "Server error: item does not exist."); else if (err == InventoryManager::ERROR_SPACE) return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "You do not have any free inventory space."); else if (err == InventoryManager::ERROR_LIMIT) return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "You already the maximum amount of these items."); else return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "Server error: undefined error."); } sim->ActivateActionAbilities(newItem); STRINGLIST result; result.push_back("OK"); sprintf(sim->Aux3, "%d", iptr->EssenceCost); result.push_back(sim->Aux3); int wpos = PrepExt_QueryResponseStringList(sim->SendBuf, query->ID, result); wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, newItem); wpos += inv.RemoveItemsAndUpdate(INV_CONTAINER, esptr->EssenceID, iptr->EssenceCost, &sim->SendBuf[wpos]); pld->charPtr->pendingChanges++; return wpos; }
void SceneryManager::SendPageRequest(const SceneryPageRequest& request, std::list<PacketManager::PACKET_PAIR>& outgoingPackets) { TimeObject to("SceneryManager::SendPageRequest"); STRINGLIST queryRows; Packet data; int wpos = 0; char idBuf[32]; GetThread("SceneryManager::HandlePageRequests[page]"); SceneryPage *page = GetOrCreatePage(request.zone, request.x, request.y); if(page == NULL) { g_Log.AddMessageFormat("[ERROR] SendPageRequest retrieved NULL page"); wpos = PrepExt_QueryResponseNull(prepBuf, request.queryID); data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); ReleaseThread(); return; } SceneryPage::SCENERY_IT it; for(it = page->mSceneryList.begin(); it != page->mSceneryList.end(); ++it) { //Build the list of scenery ID strings to form the response to the scenery.list query. //No need to save row data unless the query is required. if(request.skipQuery == false) { sprintf(idBuf, "%d", it->second.ID); queryRows.push_back(idBuf); } wpos += PrepExt_UpdateScenery(&prepBuf[wpos], &it->second); if(wpos > Global::MAX_SEND_CHUNK_SIZE) { data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); wpos = 0; } } if(wpos > 0) { data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); } //Done accessing the scenery data itself, no need to hold the thread any longer. //All the remaining stuff is using a resident list of query IDs to form into a response //packet. ReleaseThread(); //Now build the query response if the client has requested it. if(request.skipQuery == true) return; //Reset the packet buffer and data. wpos = 0; data.Clear(); //Get the size of the response int sizeReq = 6; //Query ID (4 bytes) + row count (2 bytes) for(size_t s = 0; s < queryRows.size(); s++) { sizeReq++; //1 string per row sizeReq += PutStringReq(queryRows[s].c_str()); } wpos += PutByte(&prepBuf[wpos], 1); //_handleQueryResultMsg wpos += PutShort(&prepBuf[wpos], sizeReq); //Message size wpos += PutInteger(&prepBuf[wpos], request.queryID); wpos += PutShort(&prepBuf[wpos], queryRows.size()); for(size_t s = 0; s < queryRows.size(); s++) { wpos += PutByte(&prepBuf[wpos], 1); wpos += PutStringUTF(&prepBuf[wpos], queryRows[s].c_str()); if(wpos > Global::MAX_SEND_CHUNK_SIZE) { data.Append(prepBuf, wpos); wpos = 0; } } if(wpos > 0) data.Append(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); }