Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}