static int AMXAPI amx_DGramIdle(AMX *amx, int AMXAPI Exec(AMX *, cell *, int)) { char message[BUFLEN], source[SRC_BUFSIZE]; cell *amx_addr_src; int len, chars; int err=0; assert(idxReceiveString >= 0 || idxReceivePacket >= 0); if (PrevIdle != NULL) PrevIdle(amx, Exec); /* set up listener (first call only) */ if (!dgramBound) { if (dgramPort==0) dgramPort=AMX_DGRAMPORT; /* use default port if none was set */ if (udp_Listen(dgramPort)==-1) return AMX_ERR_GENERAL; dgramBound=1; } /* if */ if (udp_IsPacket()) { len=udp_Receive(message, sizeof message / sizeof message[0], source); amx_PushString(amx,&amx_addr_src,source,1,0); /* check the presence of a byte order mark: if it is absent, the received * packet is no string; also check the packet size against string length */ if ((message[0]!='\xef' || message[1]!='\xbb' || message[2]!='\xbf' || len!=(int)strlen(message)+1 || idxReceiveString<0) && idxReceivePacket>=0) { /* receive as "packet" */ amx_Push(amx,len); amx_PushArray(amx,NULL,(cell*)message,len); err=Exec(amx,NULL,idxReceivePacket); } else { const char *msg=message; if (msg[0]=='\xef' && msg[1]=='\xbb' && msg[2]=='\xbf') msg+=3; /* skip BOM */ /* optionally convert from UTF-8 to a wide string */ if (amx_UTF8Check(msg,&chars)==AMX_ERR_NONE) { cell *array=alloca((chars+1)*sizeof(cell)); cell *ptr=array; if (array!=NULL) { while (err==AMX_ERR_NONE && *msg!='\0') amx_UTF8Get(msg,&msg,ptr++); *ptr=0; /* zero-terminate */ amx_PushArray(amx,NULL,array,chars+1); } /* if */ } else { amx_PushString(amx,NULL,msg,1,0); } /* if */ err=Exec(amx,NULL,idxReceiveString); } /* if */ while (err==AMX_ERR_SLEEP) err=Exec(amx,NULL,AMX_EXEC_CONT); amx_Release(amx,amx_addr_src); } /* if */ return err; }
PLUGIN_EXPORT int PLUGIN_CALL ProcessTick() { long long unsigned int time = MicrosecondTime(); //logprintf("Process %d", time); while (!gTimers.empty()) { struct timer_s * next = gTimers.top(); if (next->trigger > time) { return 1; } else { gTimers.pop(); //logprintf("Triggered: %d %d", next->func, next->interval); if (next->repeat) { struct params_s * p0 = next->params; while (p0) { switch (p0->type) { case PARAM_TYPE_CELL: { amx_Push(next->amx, p0->numData); break; } case PARAM_TYPE_ARRAY: case PARAM_TYPE_STRING: { // These are actually done the same way because we // just store the AMX string representation, not the // C char* representation. Just remember the NULL! amx_PushArray(next->amx, &p0->free, 0, p0->arrayData, p0->numData); break; } } p0 = p0->next; } cell ret; amx_Exec(next->amx, &ret, next->func); // Free things. p0 = next->params; while (p0) { switch (p0->type) { case PARAM_TYPE_ARRAY: case PARAM_TYPE_STRING: { amx_Release(next->amx, p0->free); p0->free = 0; break; } } p0 = p0->next; } switch (next->repeat) { case 1: DestroyTimer(next); break; default: --next->repeat; case -1: // Don't rely on the current time or we'll get errors // compounded. next->trigger += next->interval; gTimers.push(next); break; } } else { // Used by "KillTimer". DestroyTimer(next); } } } return 1; }
void CCallback::ProcessCallbacks() { CMySQLQuery *Query = NULL; while( (Query = GetNextQuery()) != NULL) { CCallback *Callback = Query->Callback; if(Callback != NULL && (Callback->Name.length() > 0 || Query->OrmObject != NULL) ) { bool PassByReference = Query->Callback->IsInline; if(Query->OrmObject != NULL) { //orm, update the variables with the given result switch(Query->OrmQueryType) { case ORM_QUERYTYPE_SELECT: Query->OrmObject->ApplySelectResult(Query->Result); break; case ORM_QUERYTYPE_INSERT: Query->OrmObject->ApplyInsertResult(Query->Result); break; } } for (list<AMX *>::iterator a = m_AmxList.begin(), end = m_AmxList.end(); a != end; ++a) { AMX *amx = (*a); cell amx_Ret; int amx_Index; cell amx_MemoryAddress = -1; if (amx_FindPublic(amx, Callback->Name.c_str(), &amx_Index) == AMX_ERR_NONE) { CLog::Get()->StartCallback(Callback->Name.c_str()); int StringIndex = Callback->ParamFormat.length()-1; while(!Callback->Parameters.empty() && StringIndex >= 0) { switch(Callback->ParamFormat.at(StringIndex)) { case 'i': case 'd': { int val = 0; ConvertStrToInt(Callback->Parameters.top().c_str(), val); if(PassByReference == false) amx_Push(amx, (cell)val); else { cell tmpAddress; amx_PushArray(amx, &tmpAddress, NULL, (cell*)&val, 1); if(amx_MemoryAddress < NULL) amx_MemoryAddress = tmpAddress; } } break; case 'f': { float float_val = 0.0f; ConvertStrToFloat(Callback->Parameters.top().c_str(), float_val); cell FParam = amx_ftoc(float_val); if(PassByReference == false) amx_Push(amx, FParam); else { cell tmpAddress; amx_PushArray(amx, &tmpAddress, NULL, (cell*)&FParam, 1); if(amx_MemoryAddress < NULL) amx_MemoryAddress = tmpAddress; } } break; default: { cell tmpAddress; amx_PushString(amx, &tmpAddress, NULL, Callback->Parameters.top().c_str(), 0, 0); if(amx_MemoryAddress < NULL) amx_MemoryAddress = tmpAddress; } } StringIndex--; Callback->Parameters.pop(); } Query->ConnHandle->SetActiveResult(Query->Result); Query->Result = NULL; amx_Exec(amx, &amx_Ret, amx_Index); if (amx_MemoryAddress >= NULL) amx_Release(amx, amx_MemoryAddress); if(Query->ConnHandle->IsActiveResultSaved() == false) delete Query->ConnHandle->GetActiveResult(); Query->ConnHandle->SetActiveResult((CMySQLResult *)NULL); CLog::Get()->EndCallback(); break; //we have found our callback, exit loop } } } Query->Destroy(); } }
int SQL_Statement::executeCallback() { status = STATEMENT_STATUS_PROCESSED; cell ret, amx_addr = -1; int funcidx; if (error == 0) { if (!amx_FindPublic(amx, callback, &funcidx)) { int a_idx = paramsArr.size(), c_idx = paramsC.size(), s_idx = paramsStr.size(); for (int i = strlen(format) - 1; i != -1; --i) { if ((i > 0) && (format[i - 1] == '&')) { amx_Push(amx, paramsC[--c_idx]); --i; // Skipping next specifier (&x). } else { cell tmp; switch (format[i]) { case 'a': case 'A': amx_PushArray(amx, &tmp, NULL, paramsArr[--a_idx].first, paramsArr[a_idx].second); if (amx_addr == -1) { amx_addr = tmp; } break; case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'i': case 'I': case 'f': case 'F': amx_Push(amx, paramsC[--c_idx]); break; case 'r': case 'R': amx_Push(amx, id); break; case 's': case 'S': amx_PushString(amx, &tmp, NULL, paramsStr[--s_idx], 0, 0); if (amx_addr == -1) { amx_addr = tmp; } break; } } } amx_Exec(amx, &ret, funcidx); } } else { if (!amx_FindPublic(amx, ERROR_CALLBACK, &funcidx)) { cell tmp; amx_PushString(amx, &amx_addr, NULL, callback, 0, 0); amx_PushString(amx, &tmp, NULL, query, 0, 0); amx_PushString(amx, &tmp, NULL, errorMsg, 0, 0); amx_Push(amx, error); amx_Push(amx, connectionId); amx_Exec(amx, &ret, funcidx); } } if (amx_addr != -1) { amx_Release(amx, amx_addr); } return ret; }