int PrepExt_GenericChatMessage(char *buffer, int creatureID, const char *name, const char *channel, const char *message) { //Handles a "communicate" (0x04) message containing a channel and string //Sends back a "_handleCommunicationMsg" (50 = 0x32) to the client //Ideally this function should broadcast the message to all active player threads //in the future so that all players can receive the communication message. int wpos = 0; wpos += PutByte(&buffer[wpos], 0x32); //_handleCommunicationMsg wpos += PutShort(&buffer[wpos], 0); //Placeholder for size wpos += PutInteger(&buffer[wpos], creatureID); //Character ID who's sending the message wpos += PutStringUTF(&buffer[wpos], name); //Character name wpos += PutStringUTF(&buffer[wpos], channel); //channel type wpos += PutStringUTF(&buffer[wpos], message); //message body PutShort(&buffer[1], wpos - 3); //Set size return wpos; }
/*-------------------------------------------------------------------------*/ long _CALLSTYLE_ SM32Post( tSM32Motor* M, long Cmd, long Data ) { WORD16 MyOffset; if( M_BASEPORT==mhSoftwareTest ) return mcrOk; /* M valid ? */ if( (M_BASEPORT < 0x100) || (M_BASEPORT & 3 ) || (((BYTE8)(M_NUMBER-1)) >2) ) return mcrNotInitialised; /* Calc channel offset */ MyOffset = oChannel[ M_NUMBER-1 ]; /* Previous command not processed yet? */ if( GetByte(M_BASEPORT, MyOffset+oFlags) & cWFlag ) return mcrBusy; /* Put Data and Command. */ PutLong( M_BASEPORT, MyOffset+oData, Data ); PutByte( M_BASEPORT, MyOffset+oWCmd, Cmd ); return mcrOk; }
int ChatManager :: handleCommunicationMsg(char *channel, char *message, char *name) { //Returns the number of bytes composing the message data. //Mostly copied from the Simulator function with the same name, but without permissions //checks. To be used internally by the server when it needs to send arbitrary messages //to clients. Should not be used for /tell messages. //Handles a "communicate" (0x04) message containing a channel and string //Sends back a "_handleCommunicationMsg" (50 = 0x32) to the client //Ideally this function should broadcast the message to all active player threads //in the future so that all players can receive the communication message. char ComBuf[1024]; char LogBuffer[1024]; if(strlen(channel) == 0 || strlen(message) == 0) return 0; //LogMessageL("[%s]:[%s]", channel, message); /* bool log = false; char *prefix = NULL; if(strcmp(channel, "s") == 0) { log = true; prefix = ChatPrefix_Say; } else if(strcmp(channel, "gm/earthsages") == 0) { log = true; prefix = ChatPrefix_GM; } else if(strcmp(channel, "*SysChat") == 0) { log = true; prefix = ChatPrefix_SysChat; } else if(strcmp(channel, "rc/") == 0) { log = true; prefix = ChatPrefix_Region; } if(log == true) { if(prefix != NULL) sprintf(LogBuffer, "%s %s: %s", prefix, name, message); else sprintf(LogBuffer, "%s: %s", name, message); LogChatMessage(LogBuffer); } else { sprintf(LogBuffer, "%s: %s", name, message); LogChatMessage(LogBuffer); }*/ int found = 0; int a; for(a = 1; a < NumValidChatChannel; a++) { if(strcmp(ValidChatChannel[a].channel, channel) == 0) { found = a; break; } } int wpos = 0; if(ValidChatChannel[found].prefix != NULL) wpos += sprintf(&LogBuffer[wpos], "%s ", ValidChatChannel[found].prefix); if(ValidChatChannel[found].name == true) wpos += sprintf(&LogBuffer[wpos], "%s: ", name); else name[0] = 0; //Disable name from showing in the data buffer wpos += sprintf(&LogBuffer[wpos], "%s", message); ChatMessage cm(message); LogChatMessage(cm); wpos = 0; wpos += PutByte(&ComBuf[wpos], 0x32); //_handleCommunicationMsg wpos += PutShort(&ComBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&ComBuf[wpos], 0); //Character ID who's sending the message wpos += PutStringUTF(&ComBuf[wpos], name); //Character name wpos += PutStringUTF(&ComBuf[wpos], channel); //return the channel type wpos += PutStringUTF(&ComBuf[wpos], message); //return the message PutShort(&ComBuf[1], wpos - 3); //Set size SIMULATOR_IT it; for(it = Simulator.begin(); it != Simulator.end(); ++it) { if(it->isConnected == true) it->AttemptSend(ComBuf, wpos); } return wpos; }
void CJpegEncoder::WriteSOF0() { PutByte(0xff); PutByte(0xc0); WORD size = 8 + 3*ColorComponents; PutByte(size>>8); PutByte(size&0xff); PutByte(8); // precision PutByte(m_h>>8); PutByte(m_h&0xff); PutByte(m_w>>8); PutByte(m_w&0xff); PutByte(ColorComponents); // color components PutByte(1); // component id PutByte(0x11); // hor | ver sampling factor PutByte(0); // quant. tbl. id PutByte(2); // component id PutByte(0x11); // hor | ver sampling factor PutByte(1); // quant. tbl. id PutByte(3); // component id PutByte(0x11); // hor | ver sampling factor PutByte(1); // quant. tbl. id }
void CJpegEncoder::WriteSOI() { PutByte(0xff); PutByte(0xd8); }
void CJpegEncoder::WriteEOI() { PutByte(0xff); PutByte(0xd9); }
void CJpegEncoder::WriteSOS() { PutByte(0xff); PutByte(0xda); WORD size = 6 + 2*ColorComponents; PutByte(size>>8); PutByte(size&0xff); PutByte(ColorComponents); // color components: 3 PutByte(1); // component id PutByte(0x00); // DC | AC huff tbl PutByte(2); // component id PutByte(0x11); // DC | AC huff tbl PutByte(3); // component id PutByte(0x11); // DC | AC huff tbl PutByte(0); // ss, first AC PutByte(63); // se, last AC PutByte(0); // ah | al static float cosuv[8][8][8][8]; // oh yeah, we don't need no fast dct :) for(int v = 0; v < 8; v++) for(int u = 0; u < 8; u++) for(int j = 0; j < 8; j++) for(int i = 0; i < 8; i++) cosuv[v][u][j][i] = (float)(cos((2*i+1)*u*PI/16) * cos((2*j+1)*v*PI/16)); int prevDC[3] = {0, 0, 0}; for(int y = 0; y < m_h; y += 8) { int jj = min(m_h - y, 8); for(int x = 0; x < m_w; x += 8) { int ii = min(m_w - x, 8); for(int c = 0; c < ColorComponents; c++) { int cc = !!c; int ACs = 0; static short block[64]; for(int zigzag = 0; zigzag < 64; zigzag++) { BYTE u = zigzagU[zigzag]; BYTE v = zigzagV[zigzag]; float F = 0; /* for(int j = 0; j < jj; j++) for(int i = 0; i < ii; i++) F += (signed char)m_p[((y+j)*m_w + (x+i))*4 + c] * cosuv[v][u][j][i]; */ for(int j = 0; j < jj; j++) { signed char* p = (signed char*)&m_p[((y+j)*m_w + x)*4 + c]; for(int i = 0; i < ii; i++, p += 4) F += *p * cosuv[v][u][j][i]; } float cu = !u ? invsq2 : 1.0f; float cv = !v ? invsq2 : 1.0f; block[zigzag] = short(2.0 / 8.0 * cu * cv * F) / quanttbl[cc][zigzag]; } short DC = block[0] - prevDC[c]; prevDC[c] = block[0]; int size = GetBitWidth(DC); PutBit(DCVLC[cc][size], DCVLC_Size[cc][size]); if(DC < 0) DC = DC - 1; PutBit(DC, size); int j; for(j = 64; j > 1 && !block[j-1]; j--); for(int i = 1; i < j; i++) { short AC = block[i]; if(AC == 0) { if(++ACs == 16) { PutBit(ACVLC[cc][15][0], ACVLC_Size[cc][15][0]); ACs = 0; } } else { int size = GetBitWidth(AC); PutBit(ACVLC[cc][ACs][size], ACVLC_Size[cc][ACs][size]); if(AC < 0) AC--; PutBit(AC, size); ACs = 0; } } if(j < 64) PutBit(ACVLC[cc][0][0], ACVLC_Size[cc][0][0]); } } } Flush(); }
void ScreenShot() { int i; char Name[40]; int width, height; unsigned char *buf = GetScreenShot24(&width, &height); if (buf == NULL) return; strcpy(Name,"avp"); int length=strlen(Name); strncpy(&Name[length],"00.bmp",8); for(i=0;i<100;i++) { Name[length]=i/10+'0'; Name[length+1]=(i%10)+'0'; FILE* tempfp = OpenGameFile(Name, FILEMODE_READONLY, FILETYPE_CONFIG); if(!tempfp)break; else { fclose(tempfp); } } if(i==100) return; FILE *fp = OpenGameFile(Name, FILEMODE_WRITEONLY, FILETYPE_CONFIG); if (!fp) { return; } BMPHEADER2 h; // fill out header h.Header.Type = 'B'+'M'*256; h.Header.Reserved1 = 0; h.Header.Reserved2 = 0; h.Header.Offset = 14+40+0; /* ** The type of information found in a BMP structure is indicated by ** the Size (Information Headere Size) field with a non-zero value. */ h.PmInfo.Size = 0; h.Pm2Info.Size = 0; h.WinInfo.Size = 40; h.WinInfo.Width = width; h.WinInfo.Height = height; h.WinInfo.Planes = 1; h.WinInfo.BitCount = 24; h.WinInfo.Compression = 0; h.WinInfo.SizeImage = h.WinInfo.Width*h.WinInfo.Height*3; h.WinInfo.XPelsPerMeter = h.WinInfo.Width; h.WinInfo.YPelsPerMeter = h.WinInfo.Height; h.WinInfo.ClrUsed = 0; h.WinInfo.ClrImportant = 0; h.Header.FileSize = h.WinInfo.SizeImage + h.Header.Offset + 8; // write header PutWord_F PutWord = PutLittleWord; PutDword_F PutDword = PutLittleDword; PutWord(h.Header.Type, fp); PutDword(h.Header.FileSize, fp); PutWord(h.Header.Reserved1, fp); PutWord(h.Header.Reserved2, fp); PutDword(h.Header.Offset, fp); PutDword(h.WinInfo.Size, fp); PutDword(h.WinInfo.Width, fp); PutDword(h.WinInfo.Height, fp); PutWord(h.WinInfo.Planes, fp); PutWord(h.WinInfo.BitCount, fp); PutDword(h.WinInfo.Compression, fp); PutDword(h.WinInfo.SizeImage, fp); PutDword(h.WinInfo.XPelsPerMeter, fp); PutDword(h.WinInfo.YPelsPerMeter, fp); PutDword(h.WinInfo.ClrUsed, fp); PutDword(h.WinInfo.ClrImportant, fp); // write 24 bit image // unsigned char *BufferPtr = &buf[(width * 3) * (height - 1)]; unsigned char *BufferPtr = &buf[0]; for (i=h.WinInfo.Height-1; i>=0; --i) { unsigned int j; for (j=0; j<h.WinInfo.Width; ++j) { PutByte((BYTE)BufferPtr[j*3+2],fp); //b PutByte((BYTE)BufferPtr[j*3+1],fp); //g PutByte((BYTE)BufferPtr[j*3],fp); //r } // pad to 4 byte boundary for (j=~(h.WinInfo.Width*3-1) & 3; j; --j) PutByte(0,fp); // BufferPtr -= width * 3; BufferPtr += width * 3; } free(buf); fclose(fp); }
int TradeStartHandler::protected_helper_query_trade_start(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { // Note: query errors don't seem to do anything in the client. // Note: The trade starter has an argument for the target player. // When the target player accepts, there is no argument to this // query. int selfPlayerID = creatureInstance->CreatureID; int otherPlayerID = 0; if (query->argCount > 0) otherPlayerID = query->GetInteger(0); ActiveInstance *actInst = creatureInstance->actInst; if (actInst == NULL) { g_Logs.simulator->error( "[%v] trade.start active instance is NULL", sim->InternalID); return QueryErrorMsg::INVALIDOBJ; } CreatureInstance *target = NULL; if (otherPlayerID != 0) { //Make sure we're not busy. if (sim->CanMoveItems() == false) return QueryErrorMsg::SELFBUSYSKILL; //Make sure the other player exists target = actInst->GetPlayerByID(otherPlayerID); if (target == NULL) return QueryErrorMsg::INVALIDOBJ; //Make sure the other player isn't busy if (actInst->tradesys.GetExistingTradeForPlayer(otherPlayerID) != NULL) return QueryErrorMsg::TRADEBUSY; if (target->simulatorPtr->CanMoveItems() == false) return QueryErrorMsg::OTHERBUSYSKILL; } //It only takes one player to start the trade for both, so initialize a //transaction for both players. int CheckID = creatureInstance->activeLootID; if (CheckID == 0) CheckID = selfPlayerID; TradeTransaction *tradeData = actInst->tradesys.GetNewTransaction(CheckID); //tradeData->Clear(); bool initiator = false; if (otherPlayerID != 0) { initiator = true; tradeData->SetPlayers(creatureInstance, target); creatureInstance->activeLootID = CheckID; target->activeLootID = CheckID; tradeData->init = true; } else { //This is the accepting player, so the target must be the origin. otherPlayerID = tradeData->player[0].selfPlayerID; target = tradeData->player[0].cInst; } if (target == NULL || otherPlayerID == 0) return QueryErrorMsg::INVALIDOBJ; tradeData->GetPlayerData(selfPlayerID)->tradeWindowOpen = true; if (initiator == true) { // Send trade request message to the other player. int wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); wpos += PutInteger(&sim->SendBuf[wpos], selfPlayerID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST); //eventType PutShort(&sim->SendBuf[1], wpos - 3); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); } else { int wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); wpos += PutInteger(&sim->SendBuf[wpos], selfPlayerID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_ACCEPTED); //eventType PutShort(&sim->SendBuf[1], wpos - 3); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); } return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "OK"); }
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)); }
int LobbyAuthenticateMessage::handleMessage(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { if(g_AccountManager.AcceptingLogins() == false) { sim->ForceErrorMessage("Not accepting more logins.", INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return 0; } char authType = GetByte(&sim->readPtr[sim->ReadPos], sim->ReadPos); AuthHandler *authHandler = g_AuthManager.GetAuthenticator(authType); if (authHandler == NULL) { g_Logs.simulator->error("[%v] Could not find authentication handler [%v]", sim->InternalID, authType); sim->ForceErrorMessage(g_Config.InvalidLoginMessage.c_str(), INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return 0; } int simID = sim->InternalID; char loginName[128]; char authHash[128]; GetStringUTF(&sim->readPtr[sim->ReadPos], loginName, sizeof(loginName), sim->ReadPos); //login name GetStringUTF(&sim->readPtr[sim->ReadPos], authHash, sizeof(authHash), sim->ReadPos); //authorization hash or or X-CSRF-Token:sess_id:session_name:uid /* Authentication can take a long time as it might now be going off to an external service. * So we put the time consuming bit into a pool thread, then return to the server thread * once that is done. */ g_Scheduler.Pool([this, simID, authHandler, loginName, authHash](){ SimulatorThread *sim = g_SimulatorManager.GetPtrByID(simID); if(sim == NULL) { g_Logs.server->error("Lost simulator %v whilst initializing authentication. Aborting.", simID); return; } std::string errorMessage; AccountData *accPtr = authHandler->authenticate(loginName, authHash, &errorMessage); g_Logs.simulator->info("Completed first phase of authentiation for %v (%v)", loginName, simID); if (accPtr == NULL) { g_Logs.simulator->error("[%v] Could not find account: %v", sim->InternalID, loginName); sim->ForceErrorMessage(g_Config.InvalidLoginMessage.c_str(), INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); } else { if(errorMessage.length() > 0) { g_Logs.simulator->error("[%v] Authentication failed for %v. %v", sim->InternalID, loginName, errorMessage); sim->ForceErrorMessage(errorMessage.c_str(), INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return; } /* Now the lengthy operation is over, complete authentication on the main server thread */ g_Logs.simulator->info("Submitting authentication on main thread for %v (%v)", accPtr->Name, simID); g_Scheduler.Submit([this, accPtr, simID](){ g_Logs.server->info("Completing authentication on main thread for %v (%v)", accPtr->Name, simID); SimulatorThread *sim = g_SimulatorManager.GetPtrByID(simID); if(sim == NULL) { g_Logs.server->error("Lost simulator %v whilst authenticating. Aborting.", simID); return; } if(g_Config.MaintenanceMessage.length() > 0 && accPtr->HasPermission(Perm_Account, Permission_Admin) == false && accPtr->HasPermission(Perm_Account, Permission_Sage) == false) { Util::SafeFormat(sim->Aux1, sizeof(sim->Aux1), "The server is currently unavailable due to mainenance. The reason given was '%s'", g_Config.MaintenanceMessage.c_str()); sim->ForceErrorMessage(sim->Aux1, INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return; } //Check for ban. if (accPtr->SuspendTimeSec >= 0) { unsigned long timePassed = g_PlatformTime.getAbsoluteSeconds() - accPtr->SuspendTimeSec; if (timePassed < accPtr->SuspendDurationSec) { unsigned long remain = accPtr->SuspendDurationSec - timePassed; Util::FormatTime(sim->Aux3, sizeof(sim->Aux3), remain); Util::SafeFormat(sim->Aux1, sizeof(sim->Aux1), "Your account has been suspended. Time remaining: %s", sim->Aux3); sim->ForceErrorMessage(sim->Aux1, INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return; } else accPtr->ClearBan(); } //Check for multiple logins. if (g_ClusterManager.CountAccountSessions(accPtr->ID) > 0) { if (accPtr->HasPermission(Perm_Account, Permission_Admin) == false) { g_SimulatorManager.CheckIdleSimulatorBoot(accPtr); sim->ForceErrorMessage("That account is already logged in.", INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_lobby_authenticate"); return; } } g_Logs.event->info("[ACCOUNT] Account '%v' logged in", accPtr->Name); //If we get here, we can successfully log into the account. accPtr->AdjustSessionLoginCount(1); g_Logs.simulator->info("[%v] Logging in as: %v [Socket:%v]", sim->InternalID, accPtr->Name, sim->sc.ClientSocket); unsigned long startTime = g_PlatformTime.getMilliseconds(); sim->LoadAccountCharacters(accPtr); g_Logs.simulator->debug("[%v] TIME PASS loading account chars: %v ms", sim->InternalID, g_PlatformTime.getMilliseconds() - startTime); int wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 50); //_handleLoginQueueMessage wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for message size wpos += PutInteger(&sim->SendBuf[wpos], 0); //Queue position PutShort(&sim->SendBuf[1], wpos - 3); sim->AttemptSend(sim->SendBuf, wpos); }); } }); return 0; }
int PrepExt_ItemDef(char *SendBuf, ItemDef *item, int ProtocolState) { int WritePos = 0; //_handleItemDefUpdateMsg is [4] for lobby, [71] for play (most common) protocol char message = 71; if(ProtocolState == 0) message = 4; WritePos += PutByte(&SendBuf[WritePos], message); WritePos += PutShort(&SendBuf[WritePos], 0); //Message size WritePos += PutInteger(&SendBuf[WritePos], item->mID); //Fill the item properties WritePos += PutByte(&SendBuf[WritePos], item->mType); WritePos += PutStringUTF(&SendBuf[WritePos], item->mDisplayName.c_str()); WritePos += PutStringUTF(&SendBuf[WritePos], item->mAppearance.c_str()); WritePos += PutStringUTF(&SendBuf[WritePos], item->mIcon.c_str()); WritePos += PutByte(&SendBuf[WritePos], item->mIvType1); WritePos += PutShort(&SendBuf[WritePos], item->mIvMax1); WritePos += PutByte(&SendBuf[WritePos], item->mIvType2); WritePos += PutShort(&SendBuf[WritePos], item->mIvMax2); WritePos += PutStringUTF(&SendBuf[WritePos], item->mSv1.c_str()); if(g_ProtocolVersion < 5) WritePos += PutInteger(&SendBuf[WritePos], item->_mCopper); WritePos += PutShort(&SendBuf[WritePos], item->mContainerSlots); WritePos += PutByte(&SendBuf[WritePos], item->mAutoTitleType); WritePos += PutShort(&SendBuf[WritePos], item->mLevel); WritePos += PutByte(&SendBuf[WritePos], item->mBindingType); WritePos += PutByte(&SendBuf[WritePos], item->mEquipType); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponType); if(item->mWeaponType != 0) { if(g_ProtocolVersion == 7) { WritePos += PutByte(&SendBuf[WritePos], item->mWeaponDamageMin); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponDamageMax); WritePos += PutByte(&SendBuf[WritePos], item->_mSpeed); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamangeRating); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamageType); } else { WritePos += PutInteger(&SendBuf[WritePos], item->mWeaponDamageMin); WritePos += PutInteger(&SendBuf[WritePos], item->mWeaponDamageMax); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamangeRating); WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamageType); } } WritePos += PutInteger(&SendBuf[WritePos], item->mEquipEffectId); WritePos += PutInteger(&SendBuf[WritePos], item->mUseAbilityId); WritePos += PutInteger(&SendBuf[WritePos], item->mActionAbilityId); WritePos += PutByte(&SendBuf[WritePos], item->mArmorType); if(item->mArmorType != 0) { if(g_ProtocolVersion == 7) { WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistMelee); WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistFire); WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistFrost); WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistMystic); WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistDeath); } else { WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistMelee); WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistFire); WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistFrost); WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistMystic); WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistDeath); } } if(g_ProtocolVersion == 7) { WritePos += PutByte(&SendBuf[WritePos], item->mBonusStrength); WritePos += PutByte(&SendBuf[WritePos], item->mBonusDexterity); WritePos += PutByte(&SendBuf[WritePos], item->mBonusConstitution); WritePos += PutByte(&SendBuf[WritePos], item->mBonusPsyche); WritePos += PutByte(&SendBuf[WritePos], item->mBonusSpirit); WritePos += PutByte(&SendBuf[WritePos], item->_mBonusHealth); WritePos += PutByte(&SendBuf[WritePos], item->mBonusWill); } else { WritePos += PutInteger(&SendBuf[WritePos], item->mBonusStrength); WritePos += PutInteger(&SendBuf[WritePos], item->mBonusDexterity); WritePos += PutInteger(&SendBuf[WritePos], item->mBonusConstitution); WritePos += PutInteger(&SendBuf[WritePos], item->mBonusPsyche); WritePos += PutInteger(&SendBuf[WritePos], item->mBonusSpirit); if(g_ProtocolVersion < 32) WritePos += PutInteger(&SendBuf[WritePos], item->_mBonusHealth); WritePos += PutInteger(&SendBuf[WritePos], item->mBonusWill); } if(g_ProtocolVersion >= 4) { WritePos += PutByte(&SendBuf[WritePos], item->isCharm); if(item->isCharm != 0) { WritePos += PutFloat(&SendBuf[WritePos], item->mMeleeHitMod); WritePos += PutFloat(&SendBuf[WritePos], item->mMeleeCritMod); WritePos += PutFloat(&SendBuf[WritePos], item->mMagicHitMod); WritePos += PutFloat(&SendBuf[WritePos], item->mMagicCritMod); WritePos += PutFloat(&SendBuf[WritePos], item->mParryMod); WritePos += PutFloat(&SendBuf[WritePos], item->mBlockMod); WritePos += PutFloat(&SendBuf[WritePos], item->mRunSpeedMod); WritePos += PutFloat(&SendBuf[WritePos], item->mRegenHealthMod); WritePos += PutFloat(&SendBuf[WritePos], item->mAttackSpeedMod); WritePos += PutFloat(&SendBuf[WritePos], item->mCastSpeedMod); WritePos += PutFloat(&SendBuf[WritePos], item->mHealingMod); } } if(g_ProtocolVersion >= 5) { WritePos += PutInteger(&SendBuf[WritePos], item->mValue); WritePos += PutByte(&SendBuf[WritePos], item->mValueType); } bool ItemUpdateDefMsgCraft = false; if(g_ProtocolVersion >= 7) ItemUpdateDefMsgCraft = true; if(ItemUpdateDefMsgCraft == true) { WritePos += PutInteger(&SendBuf[WritePos], item->resultItemId); WritePos += PutInteger(&SendBuf[WritePos], item->keyComponentId); WritePos += PutInteger(&SendBuf[WritePos], item->numberOfItems); for(size_t i = 0; i < item->craftItemDefId.size(); i++) WritePos += PutInteger(&SendBuf[WritePos], item->craftItemDefId[i]); if(item->numberOfItems != item->craftItemDefId.size()) g_Logs.server->error("Crafting material item count mismatch for ID: %v", item->mID); } if(g_ProtocolVersion >= 9) WritePos += PutStringUTF(&SendBuf[WritePos], item->mFlavorText.c_str()); if(g_ProtocolVersion >= 18) WritePos += PutByte(&SendBuf[WritePos], item->mSpecialItemType); if(g_ProtocolVersion >= 30) WritePos += PutByte(&SendBuf[WritePos], item->mOwnershipRestriction); if(g_ProtocolVersion >= 31) { WritePos += PutByte(&SendBuf[WritePos], item->mQualityLevel); WritePos += PutShort(&SendBuf[WritePos], item->mMinUseLevel); } PutShort(&SendBuf[1], WritePos - 3); return WritePos; }
bufPtr CompressStandard(bufPtr srcBuf, int flag) { if(!srcBuf) return NULL; // allocate a 2^12 sized buffer bufPtr destBuf = CreateBuffer(0x1000); if(!destBuf) return NULL; destBuf->wOffset = 0; int i = 0, j = 0, k = 0; int byte = 0; int highByte = 0; int remainder = 0; int word = 0; int identical = 0; int oldSize = srcBuf->length; comp_mode p = mode_no_compress; int n = 0; int x = 0, q = 0, r; // flag is an endianness flag as follows // flag ? bigEndian() : littleEndian(); // hence default behavior is littleEndian // int *size; this is the return size of the compressed data // after the routine has finished for(i = 0; i < oldSize; ) { byte = GetByte(srcBuf, i); // grab a char from the buffer. k = 0; // r = the same logical value (0 or 1) as q, but not the same value necesarily. r = !!q; // looking at the bytes from the start of the array up until the byte at i for some reason... for(j = 0; j < i - 1; j++) { // if( GetByte(srcBuf, j) == byte) { for(n = j; n < oldSize; n++) { if( GetByte(srcBuf, n) != GetByte(srcBuf, n + i) ) break; } if(n > k) k = n, word = j; } } identical = 0; // get the number of bytes starting at i that are identical to // the byte at i for( j = (i + 1); j < oldSize; j++ ) { if( GetByte(srcBuf, j) != byte ) break; identical++; } if( identical > (1 + r) ) p = mode_byte_repeat; else { // if looking for repeating bytes failed, we're going to try // to find a sequence of repeating words (16-bit) instead word = Get2Bytes(srcBuf, i); identical = 0; for(j = i + 2; j < oldSize; j++) { // while words are matched, the total number of actual bytes // matched is recorded, not the number of words if(Get2Bytes(srcBuf, j) != word) { if(GetByte(srcBuf, j) == byte) identical++; break; } else identical += 2; } if( identical > (2 + r) ) p = mode_word_repeat; else { // well that didn't work so we're going to try to // find an incrementing byte series // MON is iffy on how well this will actually work... // due to how the actual algorithm decompresses stuff... identical = 0; for(j = (i + 1); j < oldSize; j++) { if(GetByte(srcBuf, j) != (byte + j) ) break; identical++; } if( identical > (1 + r) ) p = mode_increment; else p = mode_no_compress; } } // what the f**k is this if( (k > r + 3) && (k > n + (p % 2)) ) { p = mode_copy; n = k; } if(!p) q++, i++; else { if(q) { q--; if(q > 0x1F) PutByte(destBuf, 0xE0 + (q >> 8) ); PutByte(destBuf, q); q++; CopyBuffer(destBuf, srcBuf, destBuf->wOffset, i - q, q); destBuf->wOffset += q; q = 0; } i += identical; identical--; if(identical > 0x1F) { PutByte(destBuf, 0xE0 + (identical >> 8) + (p << 2)); PutByte(destBuf, identical); } else PutByte(destBuf, ((p << 5)+ identical)); switch(p) { case mode_byte_repeat: case mode_increment: PutByte(destBuf, byte); break; case mode_word_repeat: Put2Bytes(destBuf, word); break; case mode_copy: if(flag) { PutByte(destBuf, word >> 8); PutByte(destBuf, word); } else { Put2Bytes(destBuf, word); } break; case mode_no_compress: default: break; }
/* * These have no purpose but to wrapper the Byte, Short & Long * functions. */ static void writeU1 (u1 const v) { file_offset++; PutByte(v); }
bool ChatManager::DeliverChatMessage(ChatMessage &message, CreatureInstance *sendingCreatureInstance) { message.mTime = time(NULL); int wpos = 0; wpos += PutByte(&SendBuf[wpos], 50); //_handleCommunicationMsg wpos += PutShort(&SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&SendBuf[wpos], message.mSenderCreatureID); //Character ID who's sending the message wpos += PutStringUTF(&SendBuf[wpos], message.mSender.c_str()); //pld.charPtr->cdef.css.display_name); //Character name wpos += PutStringUTF(&SendBuf[wpos], message.mTell ? "t/" : message.mChannel->channel); wpos += PutStringUTF(&SendBuf[wpos], message.mMessage.c_str()); PutShort(&SendBuf[1], wpos - 3); //Set size bool found = false; bool log = !message.mTell && ( message.mChannel->chatScope == CHAT_SCOPE_REGION || message.mChannel->chatScope == CHAT_SCOPE_SERVER ); bool breakLoop = false; SIMULATOR_IT it; for(it = Simulator.begin(); it != Simulator.end(); ++it) { if(breakLoop == true) break; if(it->ProtocolState == 0) { //LogMessageL(MSG_ERROR, "[WARNING] Cannot not send chat to lobby protocol simulator"); continue; } if(it->isConnected == false) continue; if(it->pld.charPtr == NULL) continue; bool send = false; if(message.mTell == true) { if(strcmp(it->pld.charPtr->cdef.css.display_name, message.mRecipient.c_str()) == 0) { send = true; found = true; } } else { switch(message.mChannel->chatScope) { case CHAT_SCOPE_LOCAL: if(sendingCreatureInstance == NULL || it->pld.CurrentInstanceID != message.mSendingInstance) break; if(ActiveInstance::GetPlaneRange(it->creatureInst, sendingCreatureInstance, LOCAL_CHAT_RANGE) > LOCAL_CHAT_RANGE) break; send = true; break; case CHAT_SCOPE_REGION: if(it->pld.CurrentInstanceID != message.mSendingInstance) break; send = true; break; case CHAT_SCOPE_SERVER: send = true; if(message.mChannelName.compare("gm/earthsages") == 0 && !it->pld.accPtr->HasPermission(Perm_Account, Permission_GMChat) && !it->pld.accPtr->HasPermission(Perm_Account, Permission_Admin)) { send = false; } break; case CHAT_SCOPE_FRIEND: if(it->pld.CreatureDefID == message.mSenderCreatureDefID) //Send to self send = true; else if(g_FriendListManager.IsMutualFriendship(it->pld.CreatureDefID, message.mSenderCreatureDefID) ==true) send = true; break; case CHAT_SCOPE_CHANNEL: { PrivateChannel *privateChannelData = g_ChatChannelManager.GetChannelForMessage(message.mSimulatorID, message.mChannelName.c_str() + 3); if(privateChannelData != NULL) { for(size_t i = 0; i < privateChannelData->mMemberList.size(); i++) if(it->InternalID == privateChannelData->mMemberList[i].mSimulatorID) send = true; } break; } case CHAT_SCOPE_PARTY: if(sendingCreatureInstance == NULL) break; g_PartyManager.BroadCastPacket(sendingCreatureInstance->PartyID, sendingCreatureInstance->CreatureDefID, SendBuf, wpos); breakLoop = true; break; case CHAT_SCOPE_CLAN: { Clans::Clan c = g_ClanManager.GetClan(message.mSenderClanID); if(it->pld.CreatureDefID == message.mSenderCreatureDefID) //Send to self send = true; else { if(c.mId > 0 && it->pld.charPtr->clan == c.mId) send = true; else if(g_GuildManager.IsMutualGuild(it->pld.CreatureDefID, message.mSenderCreatureDefID) ==true) send = true; } break; } default: break; } } if(send == true) { found = true; it->AttemptSend(SendBuf, wpos); } } if(log == true) LogChatMessage(message); return found; }
int TradeAcceptHandler::protected_helper_query_trade_accept(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { int selfID = creatureInstance->CreatureID; int tradeID = creatureInstance->activeLootID; ActiveInstance *actInst = creatureInstance->actInst; TradeTransaction *tradeData = actInst->tradesys.GetExistingTransaction( tradeID); if (tradeData == NULL) return QueryErrorMsg::TRADENOTFOUND; TradePlayerData *pData = tradeData->GetPlayerData(selfID); if (pData == NULL) return actInst->tradesys.CancelTransaction(selfID, tradeID, sim->SendBuf); CreatureInstance *cInst = pData->otherPlayerData->cInst; pData->SetAccepted(true); int wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], creatureInstance->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::OFFER_ACCEPTED); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, cInst->simulatorPtr); //actInst->LSendToOneSimulator(SendBuf, wpos, cInst->SimulatorIndex); CreatureInstance *origin = tradeData->player[0].cInst; CreatureInstance *target = tradeData->player[1].cInst; if (origin == NULL || target == NULL) return QueryErrorMsg::INVALIDOBJ; if (tradeData->MutualAccept() == true) { //Process the trade. int wpos = 0; //When counting slots, get the currently free slots. //Then add the number of items that would be traded (given away). //This allows a currently full inventory to potentially receive items //after the transaction is processed. int oslots = origin->charPtr->inventory.CountFreeSlots(INV_CONTAINER); oslots += tradeData->player[0].itemList.size(); int tslots = target->charPtr->inventory.CountFreeSlots(INV_CONTAINER); tslots += tradeData->player[1].itemList.size(); if (oslots < (int) tradeData->player[1].itemList.size()) { //Origin player does not have enough space to receive items. wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_SPACE); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Origin lacks space", sim->InternalID); goto exit; } if (tslots < (int) tradeData->player[0].itemList.size()) { //Target player does not have enough space to receive items. wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], target->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_SPACE); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Target lacks space", sim->InternalID); goto exit; } //Check that each player has the required currencies. if (tradeData->player[0].coin > origin->css.copper) { wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_FUNDS); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Origin lacks copper", sim->InternalID); goto exit; } if (tradeData->player[1].coin > target->css.copper) { wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], target->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::INSUFFICIENT_FUNDS); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Target lacks copper", sim->InternalID); goto exit; } //Ready to trade. g_Logs.simulator->debug("[%v] Trade requirements passed", sim->InternalID); //Adjust and send coin transfer to both players. origin->css.copper -= tradeData->player[0].coin; target->css.copper -= tradeData->player[1].coin; origin->css.copper += tradeData->player[1].coin; target->css.copper += tradeData->player[0].coin; static const short statSend = STAT::COPPER; wpos = PrepExt_SendSpecificStats(sim->SendBuf, origin, &statSend, 1); SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); wpos = PrepExt_SendSpecificStats(sim->SendBuf, target, &statSend, 1); SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); //Adjust and send items for first player. //Remove items from first player. wpos = 0; CharacterData *p1 = origin->charPtr; CharacterData *p2 = target->charPtr; g_Logs.simulator->debug("[%v] Trade betweeen [%v] and [%v]", sim->InternalID, p1->cdef.css.display_name, p2->cdef.css.display_name); for (size_t a = 0; a < tradeData->player[0].itemList.size(); a++) { unsigned long CCSID = tradeData->player[0].itemList[a].CCSID; InventorySlot *item = p1->inventory.GetItemPtrByCCSID(CCSID); if (item == NULL) { g_Logs.simulator->error( "[%v] Failed to remove item from first player.", sim->InternalID); } else { wpos += p1->inventory.RemoveItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item); p1->inventory.RemItem(CCSID); p1->pendingChanges++; } } SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); g_Logs.simulator->debug("[%v] Removed %v items from first player.", sim->InternalID, tradeData->player[0].itemList.size()); //Remove items from second player. wpos = 0; for (size_t a = 0; a < tradeData->player[1].itemList.size(); a++) { unsigned long CCSID = tradeData->player[1].itemList[a].CCSID; InventorySlot *item = p2->inventory.GetItemPtrByCCSID(CCSID); if (item == NULL) { g_Logs.simulator->error( "[%v] Failed to remove item from first player.", sim->InternalID); } else { wpos += p2->inventory.RemoveItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item); p2->inventory.RemItem(CCSID); p2->pendingChanges++; } } SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Removed %v items from second player.", sim->InternalID, tradeData->player[1].itemList.size()); //Give items to first player wpos = 0; for (size_t a = 0; a < tradeData->player[1].itemList.size(); a++) { int itemID = tradeData->player[1].itemList[a].IID; int count = tradeData->player[1].itemList[a].count + 1; InventorySlot *item = p1->inventory.AddItem_Ex(INV_CONTAINER, itemID, count); if (item == NULL) g_Logs.simulator->error("[%v] Failed to add item to first player.", sim->InternalID); else { p1->pendingChanges++; g_Logs.event->info("[TRADE] From %v to %v (%v)", tradeData->player[1].cInst->css.display_name, tradeData->player[0].cInst->css.display_name, item->IID); item->CopyWithoutCount(tradeData->player[1].itemList[a], false); sim->ActivateActionAbilities(item); wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item); } } SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); g_Logs.simulator->debug("[%v] Gave %v items to first player.", sim->InternalID, tradeData->player[1].itemList.size()); //Give items to second player wpos = 0; for (size_t a = 0; a < tradeData->player[0].itemList.size(); a++) { int itemID = tradeData->player[0].itemList[a].IID; int count = tradeData->player[0].itemList[a].count + 1; InventorySlot *item = p2->inventory.AddItem_Ex(INV_CONTAINER, itemID, count); if (item == NULL) g_Logs.simulator->error("[%v] Failed to add item to second player.", sim->InternalID); else { p2->pendingChanges++; g_Logs.event->info("[TRADE] From %v to %v (%v)", tradeData->player[0].cInst->css.display_name, tradeData->player[1].cInst->css.display_name, item->IID); item->CopyWithoutCount(tradeData->player[0].itemList[a], false); sim->ActivateActionAbilities(item); wpos += AddItemUpdate(&sim->SendBuf[wpos], sim->Aux3, item); } } SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); g_Logs.simulator->debug("[%v] Gave %v items to second player.", sim->InternalID, tradeData->player[0].itemList.size()); //Send trade completion message. wpos = 0; wpos += PutByte(&sim->SendBuf[wpos], 51); //_handleTradeMsg wpos += PutShort(&sim->SendBuf[wpos], 0); //Placeholder for size wpos += PutInteger(&sim->SendBuf[wpos], origin->CreatureID); //traderID wpos += PutByte(&sim->SendBuf[wpos], TradeEventTypes::REQUEST_CLOSED); //eventType wpos += PutByte(&sim->SendBuf[wpos], CloseReasons::COMPLETE); //eventType PutShort(&sim->SendBuf[1], wpos - 3); //Set message size SendToOneSimulator(sim->SendBuf, wpos, origin->simulatorPtr); //origin->actInst->LSendToOneSimulator(SendBuf, wpos, origin->SimulatorIndex); PutInteger(&sim->SendBuf[3], target->CreatureID); //traderID SendToOneSimulator(sim->SendBuf, wpos, target->simulatorPtr); //target->actInst->LSendToOneSimulator(SendBuf, wpos, target->SimulatorIndex); //Clear trade IDs. origin->activeLootID = 0; target->activeLootID = 0; g_Logs.simulator->debug("[%v] Trade complete", sim->InternalID); actInst->tradesys.RemoveTransaction(tradeID); } //Yes, I'm using goto. //Yes, I know this whole thing is badly programmed. //Deal with it. exit: return PrepExt_QueryResponseString(sim->SendBuf, query->ID, "OK"); }
void Encode() { int i,c,len,r,s,lml,cbp; unsigned char codebuf[17],mask; InitTree(); codebuf[0]=0; cbp=mask=1; s=0; r=N-F; memset(buffer,' ',r); for( len=0; len<F && (c = GetByte()) != EOF; len++ ) buffer[r+len]=c; if(len==0) return; for(i=1;i<=F;i++) InsertNode(r-i); InsertNode(r); do { if(mlen>len) mlen=len; if(mlen<=THRESHOLD) { mlen=1; codebuf[0]|=mask; codebuf[cbp++]=buffer[r]; } else { codebuf[cbp++]=(unsigned char)mpos; codebuf[cbp++]=(unsigned char)(((mpos>>4)&0xF0)|(mlen-(THRESHOLD+1))); } if((mask<<=1)==0) { for(i=0;i<cbp;i++) PutByte(codebuf[i]); codebuf[0]=0; cbp=mask=1; } lml=mlen; for(i=0;i<lml&&(c=GetByte())!=EOF;i++) { DeleteNode(s); buffer[s]=c; if(s<F-1) buffer[s+N]=c; s=(s+1)&(N-1); r=(r+1)&(N-1); InsertNode(r); } while(i++<lml) { DeleteNode(s); s=(s+1)&(N-1); r=(r+1)&(N-1); if(--len) InsertNode(r); } }while(len>0); if(cbp>1) for(i=0;i<cbp;i++) PutByte(codebuf[i]); }
int PersonaListHandler::handleQuery(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { /* Query: persona.list Args : [none] Notes: First query sent to the server. Response: Send back the list of characters available on this account. */ //Seems to be a rare condition when the account can indeed be NULL at this point. Possibly //disconnecting after the query is sent, but before it's processed? if (pld->accPtr == NULL) { g_Logs.simulator->error("[%v] persona.list null account", sim->InternalID); return 0; } g_Logs.simulator->info("Retrieving persona list for account:%v", pld->accPtr->ID); //TODO: Fix a potential buffer overflow. int WritePos = 0; WritePos += PutByte(&sim->SendBuf[WritePos], 1); //_handleQueryResultMsg WritePos += PutShort(&sim->SendBuf[WritePos], 0); //Message size WritePos += PutInteger(&sim->SendBuf[WritePos], query->ID); //Query ID //Character row count int charCount = pld->accPtr->GetCharacterCount(); if (g_ProtocolVersion >= 38) { //Version 0.8.9 has a an extra row in the beginning //with one string, the number of characters following. WritePos += PutShort(&sim->SendBuf[WritePos], charCount + 1); WritePos += PutByte(&sim->SendBuf[WritePos], 1); sprintf(sim->Aux3, "%d", charCount + 1); WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3); } else { WritePos += PutShort(&sim->SendBuf[WritePos], charCount); } g_CharacterManager.GetThread("SimulatorThread::handle_query_persona_list"); int b; for (b = 0; b < AccountData::MAX_CHARACTER_SLOTS; b++) { if (pld->accPtr->CharacterSet[b] != 0) { int cdefid = pld->accPtr->CharacterSet[b]; CharacterCacheEntry *cce = pld->accPtr->characterCache.ForceGetCharacter(cdefid); if (cce == NULL) { g_Logs.simulator->error("[%v] Could not request character: %v", sim->InternalID, cdefid); sim->ForceErrorMessage("Critical: could not load a character.", INFOMSG_ERROR); sim->Disconnect("SimulatorThread::handle_query_persona_list"); return 0; } if (g_Config.AprilFools != 0) { WritePos += PutByte(&sim->SendBuf[WritePos], 6); //6 character data strings WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->display_name.c_str()); //Seems to be sent twice in 0.8.9. Unknown purpose. WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->display_name.c_str()); WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->appearance.c_str()); const char *eqApp = cce->eq_appearance.c_str(); switch (cce->profession) { case 1: eqApp = "{[1]=3163,[0]=141760,[6]=3019,[10]=3008,[11]=2831}"; break; case 2: eqApp = "{[0]=141763,[1]=141764,[6]=2107,[10]=2442,[11]=2898}"; break; case 3: eqApp = "{[6]=2810,[10]=1980,[11]=2108,[2]=141765}"; break; case 4: eqApp = "{[2]=143609,[6]=3160,[10]=3161,[11]=3162}"; break; } WritePos += PutStringUTF(&sim->SendBuf[WritePos], eqApp); //sprintf(Aux3, "%d", cce->level); WritePos += PutStringUTF(&sim->SendBuf[WritePos], "1"); sprintf(sim->Aux3, "%d", cce->profession); WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3); if (WritePos >= (int) sizeof(sim->SendBuf)) g_Logs.server->error("Buffer overflow in persona.list"); } else { //Normal stuff. WritePos += PutByte(&sim->SendBuf[WritePos], 6); //6 character data strings WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->display_name.c_str()); //Seems to be sent twice in 0.8.9. Unknown purpose. WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->display_name.c_str()); WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->appearance.c_str()); WritePos += PutStringUTF(&sim->SendBuf[WritePos], cce->eq_appearance.c_str()); sprintf(sim->Aux3, "%d", cce->level); WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3); sprintf(sim->Aux3, "%d", cce->profession); WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3); if (WritePos >= (int) sizeof(sim->SendBuf)) g_Logs.server->error("Buffer overflow in persona.list"); } } } PutShort(&sim->SendBuf[1], WritePos - 3); //Set message size g_CharacterManager.ReleaseThread(); return WritePos; }
void OpcodesTest() { printf(">>> OpcodesTest \n"); struct State state; struct CompilationState compilationState; Mem memory[512]; InitState(&state, memory, sizeof(memory)); InitCompilationState(&compilationState, memory, sizeof(memory)); int opcodeTestOffset = 127; char* string = "OpcodeTest #1"; long len = strlen(string); memcpy(memory+opcodeTestOffset, string, len); int argNum = 0; PutCall(&compilationState, "MethodEnter"); PutByte(&compilationState, (argNum+1) * sizeof(Short)); NextInstruction(&state); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, opcodeTestOffset); NextInstruction(&state); AssertStackTopShort(&state, opcodeTestOffset); PutCall(&compilationState, "StoreShort"); PutByte(&compilationState, argNum); NextInstruction(&state); PutCall(&compilationState, "LoadByte"); PutByte(&compilationState, argNum); NextInstruction(&state); AssertStackTopByte(&state, (Byte)opcodeTestOffset); PutCall(&compilationState, "StoreByte"); PutByte(&compilationState, argNum); NextInstruction(&state); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, argNum); NextInstruction(&state); AssertStackTopShort(&state, opcodeTestOffset); PutCall(&compilationState, "PushByteToStack"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail") + CodeSizeForInstruction("Jump")); PutCall(&compilationState, "ZeroOpcodeFail"); PutCall(&compilationState, "Jump"); PutShort(&compilationState, CodeSizeForInstruction("Jump") + CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "Jump"); PutShort(&compilationState, -CodeSizeForInstruction("Jump")*2); PutCall(&compilationState, "ZeroOpcodeFail"); PutCall(&compilationState, "PassToPutS"); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); AssertStackTopShort(&state, opcodeTestOffset); NextInstruction(&state); PutCall(&compilationState, "PushByteToStack"); PutByte(&compilationState, 0); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, -CodeSizeForInstruction("JumpIf") ); NextInstruction(&state); PutCall(&compilationState, "PushByteToStack"); PutByte(&compilationState, 2); NextInstruction(&state); PutCall(&compilationState, "PushByteToStack"); PutByte(&compilationState, 2); NextInstruction(&state); PutCall(&compilationState, "CompareBytes"); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "ZeroOpcodeFail"); NextInstruction(&state); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, 2000); NextInstruction(&state); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, 2000); NextInstruction(&state); PutCall(&compilationState, "CompareShorts"); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "ZeroOpcodeFail"); NextInstruction(&state); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, 100); NextInstruction(&state); PutCall(&compilationState, "StoreByte"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "Inc"); NextInstruction(&state); PutCall(&compilationState, "Dec"); NextInstruction(&state); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "CompareShorts"); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "ZeroOpcodeFail"); NextInstruction(&state); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "DupShort"); NextInstruction(&state); PutCall(&compilationState, "CompareShorts"); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "ZeroOpcodeFail"); NextInstruction(&state); PutCall(&compilationState, "LoadByte"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "DupByte"); NextInstruction(&state); PutCall(&compilationState, "CompareBytes"); NextInstruction(&state); PutCall(&compilationState, "JumpIf"); PutShort(&compilationState, CodeSizeForInstruction("ZeroOpcodeFail")); PutCall(&compilationState, "ZeroOpcodeFail"); NextInstruction(&state); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, 1); NextInstruction(&state); PutCall(&compilationState, "DupShort"); NextInstruction(&state); PutCall(&compilationState, "Add"); NextInstruction(&state); AssertStackTopShort(&state, 200); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, -2); NextInstruction(&state); AssertStackTopShort(&state, -2); PutCall(&compilationState, "Mul"); NextInstruction(&state); AssertStackTopShort(&state, -400); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, -4); NextInstruction(&state); PutCall(&compilationState, "Div"); NextInstruction(&state); AssertStackTopShort(&state, 100); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, 99); NextInstruction(&state); PutCall(&compilationState, "Sub"); NextInstruction(&state); AssertStackTopShort(&state, 1); int methodOffset = 200; MemPtr mainPC = compilationState.PC; { compilationState.PC = compilationState.memory + methodOffset; PutCall(&compilationState, "MethodEnter"); PutByte(&compilationState, 0); PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, opcodeTestOffset); PutCall(&compilationState, "PassToPutS"); PutCall(&compilationState, "MethodExit"); } compilationState.PC = mainPC; PutCall(&compilationState, "PushShortToStack"); PutShort(&compilationState, methodOffset); NextInstruction(&state); PutCall(&compilationState, "CallStackPtr"); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); methodOffset = 200; int argValue = 0x40; PutCall(&compilationState, "PushByteToStack"); PutByte(&compilationState, argValue); PutCall(&compilationState, "Call"); PutShort(&compilationState, methodOffset); mainPC = compilationState.PC; { compilationState.PC = compilationState.memory + methodOffset; PutCall(&compilationState, "MethodEnter"); PutByte(&compilationState, 1*sizeof(Short)); PutCall(&compilationState, "SetupArgsStack"); PutCall(&compilationState, "StoreByte"); PutByte(&compilationState, 0); PutCall(&compilationState, "SetupFrameStack"); PutCall(&compilationState, "LoadShort"); PutByte(&compilationState, 0); PutCall(&compilationState, "MethodReturn"); PutByte(&compilationState, sizeof(Short)); } compilationState.PC = mainPC; NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); AssertStackTopByte(&state, argValue); NextInstruction(&state); NextInstruction(&state); NextInstruction(&state); AssertStackTopShort(&state, argValue); NextInstruction(&state); AssertStackTopShort(&state, argValue); PutCall(&compilationState, "MethodExit"); NextInstruction(&state); }
void done_outputing_bits() { PutByte(buffer<<bits_to_go); buffer = 0; /* Buffer is empty to start */ bits_to_go= 8; /* with. */ }