コード例 #1
0
ファイル: Main.cpp プロジェクト: HeIIoween/FLHook
void __stdcall GFGoodSell(const struct SGFGoodSellInfo &gsi, unsigned int iClientID)
{
	returncode = DEFAULT_RETURNCODE;

	uint iBase;
	pub::Player::GetBase(iClientID, iBase);

	multimap<uint, CARGO_MISSION>::iterator start = set_mapCargoMissions.lower_bound(iBase);
	multimap<uint, CARGO_MISSION>::iterator end = set_mapCargoMissions.upper_bound(iBase);
	for (; start != end; ++start)
	{
		if (start->second.item == gsi.iArchID)
		{
			if (start->second.curr_amount < start->second.required_amount)
			{
				int needed = start->second.required_amount - start->second.curr_amount;
				if (needed > gsi.iCount)
				{
					start->second.curr_amount += gsi.iCount;
					needed = start->second.required_amount - start->second.curr_amount;
					PrintUserCmdText(iClientID, L"%d units remaining to complete mission objective", needed);
				}
				else
				{
					PrintUserCmdText(iClientID, L"Mission objective completed",needed);
				}
			}
		}
	}
}
コード例 #2
0
    void search(const std::string &now, const std::string &end, const std::vector<std::string> &path, const std::multimap<std::string, std::string> &word_map, std::vector<std::vector<std::string> > &ans, int min_size)
    {
		if (now == end)
		{
			ans.push_back(path);
			if (path.size() < min_size)
			{
				min_size = path.size();
			}
			return;
		}
		if (path.size() > min_size)
		{
			return;
		}
		std::multimap<std::string, std::string>::const_iterator low = word_map.lower_bound(now);
		std::multimap<std::string, std::string>::const_iterator up = word_map.upper_bound(now);
		for (std::multimap<std::string, std::string>::const_iterator it = low; it != up; ++ it)
		{
			if (std::find(path.begin(), path.end(), it->second) == path.end())
			{
				std::vector<std::string> mypath = path;
				mypath.push_back(it->second);
				search(it->second, end, mypath, word_map, ans, min_size);
			}
		}
	}
コード例 #3
0
    void updateEvent(int id, int idx, float val, int activate_cmd)
    {
        idmap_t id_iter = idmap.find(id);
        if (id_iter != idmap.end())
        {
            //this is a new id
            iter_t e_iter = id_iter->second;
            Event * e = e_iter->second;
            int onset = e->onset;
            e->update(idx, val);
            e->activate_cmd(activate_cmd);
            if (onset != e->onset)
            {
                ev.erase(e_iter);

                e_iter = ev.insert(pair_t(e->onset, e));

                //TODO: optimize by thinking about whether to do ev_pos = e_iter
                ev_pos = ev.upper_bound( tick_prev );
                idmap[id] = e_iter;
            }
        }
        else
        {
            g_log->printf(1, "%s unknown note %i\n", __FUNCTION__, id);
        }
    }
コード例 #4
0
ファイル: table_search.cpp プロジェクト: trumanz/cpp-learning
 int query(float min_price, float max_price, time_t min_timestamp, time_t max_timestamp) {
      std::multimap<float, Row*>::iterator it1 = price_row_mulmap.lower_bound(min_price);
      std::multimap<float, Row*>::iterator it2 = price_row_mulmap.upper_bound(max_price);
      int count = 0;
      for(; it1 != it2; it1++) {
          if(it1->second->timestamp >= min_timestamp && it1->second->timestamp <= max_timestamp) count++;
      }
      return count;
 }  
コード例 #5
0
// starting form a list of elements, returns
// lists of lists that are all simply connected
static void recur_connect_e (const MEdge &e,
                             std::multimap<MEdge,MElement*,Less_Edge> &e2e,
                             std::set<MElement*> &group,
                             std::set<MEdge,Less_Edge> &touched){
  if (touched.find(e) != touched.end())return;
  touched.insert(e);
  for (std::multimap <MEdge,MElement*,Less_Edge>::iterator it = e2e.lower_bound(e);
         it != e2e.upper_bound(e) ; ++it){
    group.insert(it->second);
    for (int i=0;i<it->second->getNumEdges();++i){
      recur_connect_e (it->second->getEdge(i),e2e,group,touched);
    }
  }
}
コード例 #6
0
 void checkOptions(const DeckKeyword& keyword, std::multimap<std::string , PartiallySupported<T> >& map, const ParseContext& parseContext, ErrorGuard& errorGuard)
 {
     // check for partially supported keywords.
     typename std::multimap<std::string, PartiallySupported<T> >::iterator it, itlow, itup;
     itlow = map.lower_bound(keyword.name());
     itup  = map.upper_bound(keyword.name());
     for (it = itlow; it != itup; ++it) {
         const auto& record = keyword.getRecord(0);
         if (record.getItem(it->second.item).template get<T>(0) != it->second.item_value) {
             std::string msg = "For keyword '" + it->first + "' only value " + boost::lexical_cast<std::string>(it->second.item_value)
                 + " in item " + it->second.item + " is supported by flow.\n"
                 + "In file " + keyword.getFileName() + ", line " + std::to_string(keyword.getLineNumber()) + "\n";
             parseContext.handleError(ParseContext::SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED, msg, errorGuard);
         }
     }
 }
コード例 #7
0
static void recur_connect(MVertex *v,
                          std::multimap<MVertex*,MEdge> &v2e,
                          std::set<MEdge,Less_Edge> &group,
                          std::set<MVertex*> &touched)
{
  if (touched.find(v) != touched.end())return;

  touched.insert(v);
  for (std::multimap <MVertex*,MEdge>::iterator it = v2e.lower_bound(v);
       it != v2e.upper_bound(v) ; ++it){
    group.insert(it->second);
    for (int i=0;i<it->second.getNumVertices();++i){
      recur_connect (it->second.getVertex(i),v2e,group,touched);
    }
  }

}
コード例 #8
0
ファイル: Main.cpp プロジェクト: HeIIoween/FLHook
void __stdcall GFGoodBuy(struct SGFGoodBuyInfo const &gbi, unsigned int iClientID)
{
	uint iBase;
	pub::Player::GetBase(iClientID, iBase);

	multimap<uint, CARGO_MISSION>::iterator start = set_mapCargoMissions.lower_bound(iBase);
	multimap<uint, CARGO_MISSION>::iterator end = set_mapCargoMissions.upper_bound(iBase);
	for (; start != end; ++start)
	{
		if (start->second.item == gbi.iGoodID)
		{
			start->second.curr_amount -= gbi.iCount;
			if (start->second.curr_amount < 0)
			{
				start->second.curr_amount = 0;
			}
		}
	}
}
コード例 #9
0
    void addEvent(int id, char type, MYFLT * p, int np, bool in_ticks, bool active)
    {
        Event * e = new Event(type, p, np, in_ticks, active);

        idmap_t id_iter = idmap.find(id);
        if (id_iter == idmap.end())
        {
            //this is a new id
            iter_t e_iter = ev.insert(pair_t(e->onset, e));

            //TODO: optimize by thinking about whether to do ev_pos = e_iter
            ev_pos = ev.upper_bound( tick_prev );
            idmap[id] = e_iter;
        }
        else
        {
            g_log->printf(1, "%s duplicate note %i\n", __FUNCTION__, id);
        }
    }
コード例 #10
0
static void recurConnectByMEdge(const MEdge &e,
				std::multimap<MEdge, MTriangle*, Less_Edge> &e2e,
				std::set<MTriangle*> &group,
				std::set<MEdge, Less_Edge> &touched,
				std::set<MEdge, Less_Edge> &theCut)
{
  if (touched.find(e) != touched.end()) return;
  touched.insert(e);
  for (std::multimap <MEdge, MTriangle*, Less_Edge>::iterator it = e2e.lower_bound(e);
       it != e2e.upper_bound(e); ++it){
    group.insert(it->second);
    for (int i = 0; i < it->second->getNumEdges(); ++i){
      MEdge me = it->second->getEdge(i);
      if (theCut.find(me) != theCut.end()){
	touched.insert(me); //break;
      }
      else recurConnectByMEdge(me, e2e, group, touched, theCut);
    }
  }
}
コード例 #11
0
ファイル: m_alias.cpp プロジェクト: thepaul/inspircd-deb
	virtual int OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
	{
		std::multimap<std::string, Alias>::iterator i, upperbound;

		/* If theyre not registered yet, we dont want
		 * to know.
		 */
		if (user->registered != REG_ALL)
			return 0;

		/* We dont have any commands looking like this? Stop processing. */
		i = Aliases.find(command);
		if (i == Aliases.end())
			return 0;
		/* Avoid iterating on to different aliases if no patterns match. */
		upperbound = Aliases.upper_bound(command);

		irc::string c = command.c_str();
		/* The parameters for the command in their original form, with the command stripped off */
		std::string compare = original_line.substr(command.length());
		while (*(compare.c_str()) == ' ')
			compare.erase(compare.begin());

		while (i != upperbound)
		{
			if (i->second.UserCommand)
			{
				if (DoAlias(user, NULL, &(i->second), compare, original_line))
				{
					return 1;
				}
			}

			i++;
		}

		// If we made it here, no aliases actually matched.
		return 0;
	}
コード例 #12
0
ファイル: Main.cpp プロジェクト: HeIIoween/FLHook
void __stdcall ShipDestroyed(DamageList *_dmg, DWORD *ecx, uint iKill)
{
	returncode = DEFAULT_RETURNCODE;

	if (iKill)
	{
		CShip *cship = (CShip*)ecx[4];

		int iRep;
		pub::SpaceObj::GetRep(cship->get_id(), iRep);
		
		uint iAff;
		pub::Reputation::GetAffiliation(iRep, iAff);

		Vector vPos;
		vPos.x = cship->fPosX;
		vPos.y = cship->fPosY;
		vPos.z = cship->fPosZ;
		string scSector = VectorToSectorCoord(cship->iSystem, vPos);

		multimap<uint, NPC_MISSION>::iterator start = set_mapNpcMissions.lower_bound(iAff);
		multimap<uint, NPC_MISSION>::iterator end = set_mapNpcMissions.upper_bound(iAff);
		for (; start != end; ++start)
		{
			if (start->second.system == cship->iSystem)
			{
				if (start->second.sector.length() && start->second.sector != scSector)
					continue;

				if (start->second.curr_amount < start->second.required_amount)
				{
					start->second.curr_amount++;
					// PrintUserCmdText(iClientID, L"%d ships remaining to destroy to complete mission objective", needed);
				}
			}
		}
	}
}
コード例 #13
0
ファイル: sync_slave.cpp プロジェクト: Arnaud474/Warmux
bool IndexServerConn::HandleMsg(enum IndexServerMsg msg_id)
{
  switch(msg_id)
    {
    case TS_MSG_VERSION:
      return HandShake();
      break;

    case TS_MSG_WIS_VERSION:
      {
        int version;
        if (BytesReceived() < sizeof(uint32_t)) // The message is not completely received
          return true;
        if (!ReceiveInt(version)) // Receive the version number of the server index
          return false;
        if (version > VERSION)
          {
            DPRINT(INFO,"The server at %i have a version %i, while we are only running a %i version",
                   GetIP(), version, VERSION);
            exit(EXIT_FAILURE);
          }
        else if(version < VERSION)
          {
            DPRINT(INFO,"This server is running an old version (v%i) !", version);
            return false;
          }
        DPRINT(INFO,"We are running the same version..");
      }
      break;
    case TS_MSG_JOIN_LEAVE:
      {
        int ip;
        int port;
        std::string version;

        if (!ReceiveStr(version))
            return false;

        if (BytesReceived() < 2*sizeof(uint32_t)) // The message is not completely received
          return true;
        if (!ReceiveInt(ip)) // Receive the IP of the warmux server
          return false;
        if (!ReceiveInt(port)) // Receive the port of the warmux server
          return false;

        if (port < 0) // means it disconnected
          {
	    for (std::multimap<std::string, FakeClient>::iterator serv = fake_clients.lower_bound(version);
		 serv != fake_clients.upper_bound(version);
		 serv++) {

	      if( serv->second.ip == ip
		  &&  serv->second.port == -port )
		{
		  fake_clients.erase(serv);
		  DPRINT(MSG, "A fake server disconnected");
		  break;
		}
	    }
          }
        else
          {
            HostOptions options;

	    std::string game_name;
	    if (!ReceiveStr(game_name))
	      return false;

	    int passwd;
	    if (!ReceiveInt(passwd))
	      return false;
	    options.Set(game_name, passwd);

            fake_clients.insert(std::make_pair(version, FakeClient(ip, port, options)));
            stats.NewFakeServer(version);
          }
      }
      break;
    default:
      DPRINT(INFO,"Bad message!");
      return false;
    }
  msg_id = TS_NO_MSG;
  return true;
}
コード例 #14
0
ファイル: fn_engine.cpp プロジェクト: Asmodean-/Vulkan
VkBool32 VKTS_APIENTRY engineRun()
{
    if (g_engineState != VKTS_ENGINE_INIT_STATE)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Not in initialize state.");

        return VK_FALSE;
    }

    if (engineGetNumberUpdateThreads() < VKTS_MIN_UPDATE_THREADS || engineGetNumberUpdateThreads() > VKTS_MAX_UPDATE_THREADS)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Number of update threads not correct.");

        return VK_FALSE;
    }

    //
    // Main thread gets all displays and windows attached.
    //

    const auto& displayList = _visualGetActiveDisplays();

    for (size_t i = 0; i < displayList.size(); i++)
    {
        engineAttachDisplayToUpdateThread(displayList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    const auto& windowList = _visualGetActiveWindows();

    for (size_t i = 0; i < windowList.size(); i++)
    {
        engineAttachWindowToUpdateThread(windowList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    //

    g_engineState = VKTS_ENGINE_UPDATE_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Started.");

    // Task queue creation.

    TaskQueueSP sendTaskQueue;
    TaskQueueSP executedTaskQueue;

    if (g_taskExecutorCount > 0)
    {
        sendTaskQueue = TaskQueueSP(new TaskQueue);

        if (!sendTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }

        executedTaskQueue = TaskQueueSP(new TaskQueue);

        if (!executedTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }
    }

    // Message dispatcher creation.

    MessageDispatcherSP messageDispatcher = MessageDispatcherSP(new MessageDispatcher());

    if (!messageDispatcher.get())
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create message dispatcher.");

        return VK_FALSE;
    }

    // Object, needed for synchronizing the executors.

    ExecutorSync executorSync;

    //
    // Task executor creation and launching,
    //

    SmartPointerVector<TaskExecutorSP> realTaskExecutors;
    SmartPointerVector<ThreadSP> realTaskThreads;

    for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    {
        auto currentTaskExecutor = TaskExecutorSP(new TaskExecutor(i, executorSync, sendTaskQueue, executedTaskQueue));

        if (!currentTaskExecutor.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current task executor.");

            return VK_FALSE;
        }

        auto currentRealThread = ThreadSP(new std::thread(&TaskExecutor::run, currentTaskExecutor));

        if (!currentRealThread.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

            return VK_FALSE;
        }

        //

        realTaskExecutors.append(currentTaskExecutor);
        realTaskThreads.append(currentRealThread);

        logPrint(VKTS_LOG_INFO, "Engine: Task %d started.", currentTaskExecutor->getIndex());
    }

    //
    // Update Thread creation and launching.
    //

    UpdateThreadExecutorSP mainUpdateThreadExecutor;

    SmartPointerVector<UpdateThreadExecutorSP> realUpdateThreadExecutors;
    SmartPointerVector<ThreadSP> realUpdateThreads;

    int32_t index = 0;

    for (size_t updateThreadIndex = 0; updateThreadIndex < g_allUpdateThreads.size(); updateThreadIndex++)
    {
        const auto& currentUpdateThread = g_allUpdateThreads[updateThreadIndex];

        //

        const auto currentMessageDispatcher = (index == engineGetNumberUpdateThreads() - 1) ? messageDispatcher : MessageDispatcherSP();

        //

        auto currentUpdateThreadContext = UpdateThreadContextSP(new UpdateThreadContext((int32_t) updateThreadIndex, (int32_t) g_allUpdateThreads.size(), g_tickTime, sendTaskQueue, executedTaskQueue));

        if (!currentUpdateThreadContext.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create update thread context.");

            return VK_FALSE;
        }

        //

        for (auto currentDisplayWalker = g_allAttachedDisplays.lower_bound(currentUpdateThread); currentDisplayWalker != g_allAttachedDisplays.upper_bound(currentUpdateThread); currentDisplayWalker++)
        {
            currentUpdateThreadContext->attachDisplay(currentDisplayWalker->second);
        }

        //

        for (auto currentWindowWalker = g_allAttachedWindows.lower_bound(currentUpdateThread); currentWindowWalker != g_allAttachedWindows.upper_bound(currentUpdateThread); currentWindowWalker++)
        {
            currentUpdateThreadContext->attachWindow(currentWindowWalker->second);
        }

        //

        if (index == engineGetNumberUpdateThreads() - 1)
        {
            // Last thread is the main thread.
            mainUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!mainUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create main update thread executor.");

                return VK_FALSE;
            }
        }
        else
        {
            // Receive queue is the threads send queue.
            auto currentUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!currentUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current update thread executor.");

                return VK_FALSE;
            }

            realUpdateThreadExecutors.append(currentUpdateThreadExecutor);

            logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", currentUpdateThreadExecutor->getIndex());

            auto currentRealThread = ThreadSP(new std::thread(&UpdateThreadExecutor::run, currentUpdateThreadExecutor));

            if (!currentRealThread.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

                return VK_FALSE;
            }
            realUpdateThreads.append(currentRealThread);
        }
        index++;
    }

    // Run last thread and loop.
    logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", mainUpdateThreadExecutor->getIndex());

    mainUpdateThreadExecutor->run();

    //
    // Stopping everything.
    //

    logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", mainUpdateThreadExecutor->getIndex());

    // Wait for all threads to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realUpdateThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realUpdateThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", reverseIndex);
    }

    realUpdateThreadExecutors.clear();
    realUpdateThreads.clear();

    //

    if (sendTaskQueue.get())
    {
    	// Empty the queue.
    	// As no update thread can feed the queue anymore, it is save to call reset.

    	sendTaskQueue->reset();

    	//

    	ITaskSP stopTask;

        logPrint(VKTS_LOG_SEVERE, "Engine: Disabling task queue.");

    	for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    	{
    		// Send an empty task to the queue, to exit the thread.
    		sendTaskQueue->addTask(stopTask);
    	}
    }

    // Wait for all tasks to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realTaskThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realTaskThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Task %d stopped.", reverseIndex);
    }

    realTaskExecutors.clear();
    realTaskThreads.clear();

    //

    g_engineState = VKTS_ENGINE_INIT_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Stopped.");

    return VK_TRUE;
}
コード例 #15
0
ファイル: CubitLoops.hpp プロジェクト: chrismullins/cgma
template <class C, class V> inline
bool CubitLoops<C, V>::recursive_make_loop(V* start_vertex, CoEdge* coedge,
    std::set<CoEdge* >& used_coedges,
    std::multimap<V*, CoEdge*>& start_coedge_map,
    std::vector<CoEdge*>& loop)
{
  V* curr_vertex;
  if (coedge->sense == CUBIT_FORWARD)
    curr_vertex = coedge->end;
  else
    curr_vertex = coedge->start;
  loop.push_back(coedge);
  used_coedges.insert(coedge);

  while (curr_vertex != start_vertex) 
  {
    typename std::multimap<V*, CoEdge*>::iterator iter;
    typename std::multimap<V*, CoEdge*>::iterator last;

    iter = start_coedge_map.lower_bound(curr_vertex);
    last = start_coedge_map.upper_bound(curr_vertex);

    std::vector<CoEdge*> possible_coedges;
    for (/*preinitialized*/; iter != last; iter++)
    {
      if (used_coedges.find(iter->second) == used_coedges.end())
        possible_coedges.push_back(iter->second);
    }

    if (possible_coedges.size() == 0)
      return false;
    else if (possible_coedges.size() == 1)
    {
      coedge = possible_coedges[0];
      loop.push_back(coedge);
      used_coedges.insert(coedge);
      if (coedge->sense == CUBIT_FORWARD)
        curr_vertex = coedge->end;
      else
        curr_vertex = coedge->start;
    }
    else
    {
      for (size_t i=0; i<possible_coedges.size(); i++)
      {
        std::vector<CoEdge*> sub_loop;
        if (recursive_make_loop(curr_vertex, possible_coedges[i], used_coedges, start_coedge_map, sub_loop) )
        {
          loop.insert(loop.end(), sub_loop.begin(), sub_loop.end());
        }
        else
        {
          for (size_t j=0; j<sub_loop.size(); j++)
            used_coedges.erase(sub_loop[j]);
          coedge = possible_coedges[i];
        }
      }
      loop.push_back(coedge);
      used_coedges.insert(coedge);
      if (coedge->sense == CUBIT_FORWARD)
        curr_vertex = coedge->end;
      else
        curr_vertex = coedge->start;
    }
  }

  return true;
}
コード例 #16
0
ファイル: m_alias.cpp プロジェクト: thepaul/inspircd-deb
	virtual void OnUserMessage(User *user, void *dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
	{
		if (target_type != TYPE_CHANNEL)
		{
			return;
		}

		// fcommands are only for local users. Spanningtree will send them back out as their original cmd.
		if (!user || !IS_LOCAL(user))
		{
			return;
		}

		/* Stop here if the user is +B and allowbot is set to no. */
		if (!AllowBots && user->IsModeSet('B'))
		{
			return;
		}

		Channel *c = (Channel *)dest;
		std::string fcommand;

		// text is like "!moo cows bite me", we want "!moo" first
		irc::spacesepstream ss(text);
		ss.GetToken(fcommand);

		if (fcommand.empty())
		{
			return; // wtfbbq
		}

		// we don't want to touch non-fantasy stuff
		if (*fcommand.c_str() != fprefix)
		{
			return;
		}

		// nor do we give a shit about the prefix
		fcommand.erase(fcommand.begin());
		std::transform(fcommand.begin(), fcommand.end(), fcommand.begin(), ::toupper);

		std::multimap<std::string, Alias>::iterator i = Aliases.find(fcommand);

		if (i == Aliases.end())
			return;

		/* Avoid iterating on to other aliases if no patterns match */
		std::multimap<std::string, Alias>::iterator upperbound = Aliases.upper_bound(fcommand);


		/* The parameters for the command in their original form, with the command stripped off */
		std::string compare = text.substr(fcommand.length() + 1);
		while (*(compare.c_str()) == ' ')
			compare.erase(compare.begin());

		while (i != upperbound)
		{
			if (i->second.ChannelCommand)
			{
				// We use substr(1) here to remove the fantasy prefix
				if (DoAlias(user, c, &(i->second), compare, text.substr(1)))
					return;
			}

			i++;
		}

		return;
	}