示例#1
0
StdStrBuf C4FileSelDlg::GetSelection(const char *szFixedSelection,
                                     bool fFilenameOnly) const {
  StdStrBuf sResult;
  if (!IsMultiSelection()) {
    // get single selected file for single selection dlg
    if (pSelection)
      sResult.Copy(fFilenameOnly ? GetFilename(pSelection->GetFilename())
                                 : pSelection->GetFilename());
  } else {
    // force fixed selection first
    if (szFixedSelection) sResult.Append(szFixedSelection);
    //  get ';'-seperated list for multi selection dlg
    for (ListItem *pFileItem =
             static_cast<ListItem *>(pFileListBox->GetFirst());
         pFileItem; pFileItem = static_cast<ListItem *>(pFileItem->GetNext()))
      if (pFileItem->IsChecked()) {
        const char *szAppendFilename = pFileItem->GetFilename();
        if (fFilenameOnly) szAppendFilename = GetFilename(szAppendFilename);
        // prevent adding entries twice (especially those from the fixed
        // selection list)
        if (!SIsModule(sResult.getData(), szAppendFilename)) {
          if (sResult.getLength()) sResult.AppendChar(';');
          sResult.Append(szAppendFilename);
        }
      }
  }
  return sResult;
}
示例#2
0
StdStrBuf C4MusicFileOgg::GetDebugInfo() const
{
	StdStrBuf result;
	result.Append(FileName);
	result.AppendFormat("[%.0lf]", last_playback_pos_sec);
	result.AppendChar('[');
	bool sec = false;
	for (auto i = categories.cbegin(); i != categories.cend(); ++i)
	{
		if (sec) result.AppendChar(',');
		result.Append(i->getData());
		sec = true;
	}
	result.AppendChar(']');
	return result;
}
示例#3
0
StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug)
{

	// At the start of the shader set the #version and number of
	// available uniforms
	StdStrBuf Buf;
#ifndef USE_CONSOLE
	GLint iMaxFrags = 0, iMaxVerts = 0;
	glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &iMaxFrags);
	glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &iMaxVerts);
#else
	int iMaxFrags = INT_MAX, iMaxVerts = INT_MAX;
#endif
	Buf.Format("#version %d\n"
			   "#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n"
			   "#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n",
			   C4Shader_Version, iMaxFrags, iMaxVerts);

	// Put slices
	int iPos = -1, iNextPos = -1;
	do
	{
		iPos = iNextPos; iNextPos = C4Shader_LastPosition+1;
		// Add all slices at the current level
		if (fDebug && iPos > 0)
			Buf.AppendFormat("\t// Position %d:\n", iPos);
		for (ShaderSliceList::const_iterator pSlice = Slices.begin(); pSlice != Slices.end(); pSlice++)
		{
			if (pSlice->Position < iPos) continue;
			if (pSlice->Position > iPos)
			{
				iNextPos = Min(iNextPos, pSlice->Position);
				continue;
			}
			// Same position - add slice!
			if (fDebug)
			{
				if (pSlice->Source.getLength())
					Buf.AppendFormat("\t// Slice from %s:\n", pSlice->Source.getData());
				else
					Buf.Append("\t// Built-in slice:\n");
				}
			Buf.Append(pSlice->Text);
			if (Buf[Buf.getLength()-1] != '\n')
				Buf.AppendChar('\n');
		}
		// Add seperator - only priority (-1) is top-level
		if (iPos == -1) {
			Buf.Append("void main() {\n");
		}
	}
	while (iNextPos <= C4Shader_LastPosition);

	// Terminate
	Buf.Append("}\n");
	return Buf;
}
示例#4
0
bool LogFatal(const char *szMessage)
{
	if (!szMessage) szMessage = "(null)";
	// add to fatal error message stack - if not already in there (avoid duplication)
	if (!SSearch(sFatalError.getData(), szMessage))
	{
		if (!sFatalError.isNull()) sFatalError.AppendChar('|');
		sFatalError.Append(szMessage);
	}
	// write to log - note that Log might overwrite a static buffer also used in szMessage
	return !!Log(FormatString(LoadResStr("IDS_ERR_FATAL"), szMessage).getData());
}
示例#5
0
bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg)
	{
	// name by file
	Name.Copy(GetFilenameOnly(szFilename));
#if defined(_WIN32) && !defined(HAVE_FREETYPE)
	// check whether group is directory or packed
	if (!hGrp.IsPacked())
		{
		// it's open: use the file directly
		SCopy(hGrp.GetFullName().getData(), FileName, _MAX_PATH);
		AppendBackslash(FileName);
		SAppend(szFilename, FileName);
		if (!FileExists(FileName)) { *FileName=0; return false; }
		fIsTempFile = false;
		}
	else
		{
		// it's packed: extract to temp path
		SCopy(rCfg.AtTempPath(szFilename), FileName, _MAX_PATH);
		// make sure the filename is not in use, in case multiple instances of the engine are run
		if (FileExists(FileName))
			{
			RemoveExtension(FileName);
			StdStrBuf sNewFilename;
			for (int i=0; i<1000; ++i)
				{
				sNewFilename.Format("%s%x", FileName, (int)rand());
				if (*GetExtension(szFilename))
					{
					sNewFilename.AppendChar('.');
					sNewFilename.Append(GetExtension(szFilename));
					}
				if (!FileExists(sNewFilename.getData())) break;
				}
			SCopy(sNewFilename.getData(), FileName, _MAX_PATH);
			}
		if (!hGrp.ExtractEntry(szFilename, FileName)) { *FileName=0; return false; }
		fIsTempFile = true;
		}
	// add the font resource
	//if (!AddFontResourceEx(FileName, FR_PRIVATE, NULL)) requires win2k
	if (!AddFontResource(FileName))
		{
		if (fIsTempFile) EraseFile(FileName);
		*FileName='\0';
		return false;
		}
#else
	if (!hGrp.LoadEntry(szFilename, Data)) return false;
#endif
	// success
	return true;
	}
示例#6
0
StdStrBuf C4PropListStatic::GetDataString() const
{
	StdStrBuf r;
	if (Parent)
	{
		r.Take(Parent->GetDataString());
		r.AppendChar('.');
	}
	assert(ParentKeyName);
	if (ParentKeyName)
		r.Append(ParentKeyName->GetData());
	return r;
}
bool C4MusicSystem::InitForScenario(C4Group & hGroup)
{
	// check if the scenario contains music
	bool fLocalMusic = false;
	StdStrBuf MusicDir;
	if (GrpContainsMusic(hGroup))
	{
		// clear global songs
		ClearSongs();
		fLocalMusic = true;
		// add songs
		MusicDir.Take(Game.ScenarioFile.GetFullName());
		LoadDir(MusicDir.getData());
		// log
		LogF(LoadResStr("IDS_PRC_LOCALMUSIC"), MusicDir.getData());
	}
	// check for music folders in group set
	C4Group *pMusicFolder = NULL;
	while ((pMusicFolder = Game.GroupSet.FindGroup(C4GSCnt_Music, pMusicFolder)))
	{
		if (!fLocalMusic)
		{
			// clear global songs
			ClearSongs();
			fLocalMusic = true;
		}
		// add songs
		MusicDir.Take(pMusicFolder->GetFullName());
		MusicDir.AppendChar(DirectorySeparator);
		MusicDir.Append(C4CFN_Music);
		LoadDir(MusicDir.getData());
		// log
		LogF(LoadResStr("IDS_PRC_LOCALMUSIC"), MusicDir.getData());
	}
	// no music?
	if (!SongCount) return false;
	// set play list
	SetPlayList(0);
	// ok
	return true;
}
示例#8
0
StdStrBuf C4KeyCodeEx::ToString(bool fHumanReadable, bool fShort) const
{
    static StdStrBuf sResult;
    sResult.Clear();
    // Add shift
    for (DWORD dwShiftCheck = KEYS_First; dwShiftCheck <= KEYS_Max; dwShiftCheck <<= 1)
        if (dwShiftCheck & dwShift)
        {
            sResult.Append(KeyShift2String((C4KeyShiftState) dwShiftCheck));
            sResult.AppendChar('+');
        }
    // Add key
    if (sResult.getLength())
    {
        sResult.Append(KeyCode2String(Key, fHumanReadable, fShort));
        return sResult;
    }
    else
    {
        return KeyCode2String(Key, fHumanReadable, fShort);
    }
}
示例#9
0
StdStrBuf C4Team::GetNameWithParticipants() const
{
	// compose team name like "Team 1 (boni, GhostBear, Clonko)"
	// or just "Team 1" for empty team
	StdStrBuf sTeamName;
	sTeamName.Copy(GetName());
	if (GetPlayerCount())
	{
		sTeamName.Append(" (");
		int32_t iTeamPlrCount=0;
		for (int32_t j=0; j<GetPlayerCount(); ++j)
		{
			int32_t iPlr = GetIndexedPlayer(j);
			C4PlayerInfo *pPlrInfo;
			if (iPlr) if  ((pPlrInfo = Game.PlayerInfos.GetPlayerInfoByID(iPlr)))
				{
					if (iTeamPlrCount++) sTeamName.Append(", ");
					sTeamName.Append(pPlrInfo->GetName());
				}
		}
		sTeamName.AppendChar(')');
	}
	return sTeamName;
}
示例#10
0
void C4Network2IRCClient::OnNumericCommand(const char *szSender, int iCommand, const char *szParameters)
	{
	bool fShowMessage = true;
	// Get target
	StdStrBuf Target = ircExtractPar(&szParameters);
	// Handle command
	switch(iCommand)
		{

		case 433: // Nickname already in use
			{
			StdStrBuf DesiredNick = ircExtractPar(&szParameters);
			// Automatically try to choose a new one
			DesiredNick.AppendChar('_');
			Send("NICK", DesiredNick.getData());
			break;
			}

		case 376: // End of MOTD
		case 422: // MOTD missing
			// Let's take this a sign that the connection is established.
			OnConnected();
			break;

		case 331: // No topic set
		case 332: // Topic notify / change
			{
			// Get Channel name and topic
			StdStrBuf Channel = ircExtractPar(&szParameters);
			StdStrBuf Topic = (iCommand == 332 ? ircExtractPar(&szParameters) : StdStrBuf(""));
			// Set it
			AddChannel(Channel.getData())->OnTopic(Topic.getData());
			// Log
			if(Topic.getLength())
				PushMessage(MSG_Status, szSender, Channel.getData(), FormatString(LoadResStr("IDS_MSG_TOPICIN"), Channel.getData(), Topic.getData()).getData());
			}
			break;

		case 333: // Last topic change
			fShowMessage = false; // ignore
			break;

		case 353: // Names in channel
			{
			// Get Channel name and name list
			StdStrBuf Junk = ircExtractPar(&szParameters); // ??!
			StdStrBuf Channel = ircExtractPar(&szParameters);
			StdStrBuf Names = ircExtractPar(&szParameters);
			// Set it
			AddChannel(Channel.getData())->OnUsers(Names.getData(), Prefixes.getData());
			fShowMessage = false;
			}
			break;

		case 366: // End of names list
			{
			// Get Channel name
			StdStrBuf Channel = ircExtractPar(&szParameters);
			// Finish
			AddChannel(Channel.getData())->OnUsersEnd();
			fShowMessage = false;
      // Notify
      if(pNotify) pNotify->PushEvent(Ev_IRC_Message, this);
			}
			break;

		case 4: // Server version
			fShowMessage = false; // ignore
			break;

		case 5: // Server support string
			{
			while(szParameters && *szParameters)
				{
				// Get support-token.
				StdStrBuf Token = ircExtractPar(&szParameters);
				StdStrBuf Parameter; Parameter.CopyUntil(Token.getData(), '=');
				// Check if it's interesting and safe data if so.
				if(SEqualNoCase(Parameter.getData(), "PREFIX"))
					Prefixes.Copy(SSearch(Token.getData(), "="));
				}
			fShowMessage = false;
			}
			break;

		}
	// Show embedded message, if any?
	if(fShowMessage)
		{
		// Check if first parameter is some sort of channel name
		C4Network2IRCChannel *pChannel = NULL;
		if(szParameters && *szParameters && *szParameters != ':')
			pChannel = getChannel(ircExtractPar(&szParameters).getData());
		// Go over other parameters
		const char *pMsg = szParameters;
		while(pMsg && *pMsg && *pMsg != ':')
			pMsg = SSearch(pMsg, " ");
		// Show it
		if(pMsg && *pMsg)
			if(!pChannel)
				PushMessage(MSG_Server, szSender, Nick.getData(), pMsg + 1);
			else
				PushMessage(MSG_Status, szSender, pChannel->getName(), pMsg + 1);
		}
	}
示例#11
0
bool C4MessageInput::ProcessCommand(const char *szCommand) {
  C4GameLobby::MainDlg *pLobby = Game.Network.GetLobby();
  // command
  char szCmdName[C4MaxName + 1];
  SCopyUntil(szCommand + 1, szCmdName, ' ', C4MaxName);
  // parameter
  const char *pCmdPar = SSearch(szCommand, " ");
  if (!pCmdPar) pCmdPar = "";

  // dev-scripts
  if (SEqual(szCmdName, "help")) {
    LogF(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGGA"));
    LogF("/private [player] [message] - %s",
         LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES"));
    LogF("/team [message] - %s",
         LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR"));
    LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME"));
    LogF("/sound [sound] - %s",
         LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO"));
    LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT"));
    LogF("/observer [client] - %s",
         LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB"));
    LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA"));
    LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE"));
    LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS"));
    LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU"));
    LogF("/set comment [comment] - %s",
         LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT"));
    LogF("/set password [password] - %s",
         LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD"));
    LogF("/set faircrew [on/off] - %s",
         LoadResStr("IDS_TEXT_ENABLEORDISABLEFAIRCREW"));
    LogF("/set maxplayer [4] - %s",
         LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA"));
    LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND"));
    LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD"));
    return TRUE;
  }
  // dev-scripts
  if (SEqual(szCmdName, "script")) {
    if (!Game.IsRunning) return FALSE;
    if (!Game.DebugMode) return FALSE;
    if (!Game.Network.isEnabled() &&
        !SEqual(Game.ScenarioFile.GetMaker(), Config.General.Name) &&
        Game.ScenarioFile.GetStatus() != GRPF_Folder)
      return FALSE;
    if (Game.Network.isEnabled() && !Game.Network.isHost()) return FALSE;

    Game.Control.DoInput(
        CID_Script,
        new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console, false),
        CDT_Decide);
    return TRUE;
  }
  // set runtimte properties
  if (SEqual(szCmdName, "set")) {
    if (SEqual2(pCmdPar, "maxplayer ")) {
      if (Game.Control.isCtrlHost()) {
        if (atoi(pCmdPar + 10) == 0 && !SEqual(pCmdPar + 10, "0")) {
          Log("Syntax: /set maxplayer count");
          return FALSE;
        }
        Game.Control.DoInput(
            CID_Set, new C4ControlSet(C4CVT_MaxPlayer, atoi(pCmdPar + 10)),
            CDT_Decide);
        return TRUE;
      }
    }
    if (SEqual2(pCmdPar, "comment ") || SEqual(pCmdPar, "comment")) {
      if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE;
      // Set in configuration, update reference
      Config.Network.Comment.CopyValidated(pCmdPar[7] ? (pCmdPar + 8) : "");
      Game.Network.InvalidateReference();
      Log(LoadResStr("IDS_NET_COMMENTCHANGED"));
      return TRUE;
    }
    if (SEqual2(pCmdPar, "password ") || SEqual(pCmdPar, "password")) {
      if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE;
      Game.Network.SetPassword(pCmdPar[8] ? (pCmdPar + 9) : NULL);
      if (pLobby) pLobby->UpdatePassword();
      return TRUE;
    }
    if (SEqual2(pCmdPar, "faircrew ")) {
      if (!Game.Control.isCtrlHost() || Game.Parameters.isLeague())
        return FALSE;
      C4ControlSet *pSet = NULL;
      if (SEqual(pCmdPar + 9, "on"))
        pSet =
            new C4ControlSet(C4CVT_FairCrew, Config.General.FairCrewStrength);
      else if (SEqual(pCmdPar + 9, "off"))
        pSet = new C4ControlSet(C4CVT_FairCrew, -1);
      else if (isdigit((unsigned char)pCmdPar[9]))
        pSet = new C4ControlSet(C4CVT_FairCrew, atoi(pCmdPar + 9));
      else
        return FALSE;
      Game.Control.DoInput(CID_Set, pSet, CDT_Decide);
      return TRUE;
    }
    // unknown property
    return FALSE;
  }
  // get szen from network folder - not in lobby; use res tab there
  if (SEqual(szCmdName, "netgetscen")) {
    if (Game.Network.isEnabled() && !Game.Network.isHost() && !pLobby) {
      const C4Network2ResCore *pResCoreScen =
          Game.Parameters.Scenario.getResCore();
      if (pResCoreScen) {
        C4Network2Res::Ref pScenario =
            Game.Network.ResList.getRefRes(pResCoreScen->getID());
        if (pScenario)
          if (C4Group_CopyItem(
                  pScenario->getFile(),
                  Config.AtExePath(GetFilename(Game.ScenarioFilename)))) {
            LogF(LoadResStr("IDS_MSG_CMD_NETGETSCEN_SAVED"),
                 Config.AtExePath(GetFilename(Game.ScenarioFilename)));
            return TRUE;
          }
      }
    }
    return FALSE;
  }
  // clear message board
  if (SEqual(szCmdName, "clear")) {
    // lobby
    if (pLobby) {
      pLobby->ClearLog();
    }
    // fullscreen
    else if (Game.GraphicsSystem.MessageBoard.Active)
      Game.GraphicsSystem.MessageBoard.ClearLog();
    else {
      // EM mode
      Console.ClearLog();
    }
    return TRUE;
  }
  // kick client
  if (SEqual(szCmdName, "kick")) {
    if (Game.Network.isEnabled() && Game.Network.isHost()) {
      // find client
      C4Client *pClient = Game.Clients.getClientByName(pCmdPar);
      if (!pClient) {
        LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar);
        return FALSE;
      }
      // league: Kick needs voting
      if (Game.Parameters.isLeague() &&
          Game.Players.GetAtClient(pClient->getID()))
        Game.Network.Vote(VT_Kick, true, pClient->getID());
      else
        // add control
        Game.Clients.CtrlRemove(pClient,
                                LoadResStr("IDS_MSG_KICKFROMMSGBOARD"));
    }
    return TRUE;
  }
  // set fast mode
  if (SEqual(szCmdName, "fast")) {
    if (!Game.IsRunning) return FALSE;
    if (Game.Parameters.isLeague()) {
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
      return FALSE;
    }
    int32_t iFS;
    if ((iFS = atoi(pCmdPar)) == 0) return FALSE;
    // set frameskip and fullspeed flag
    Game.FrameSkip = BoundBy<int32_t>(iFS, 1, 500);
    Game.FullSpeed = TRUE;
    // start calculation immediatly
    Application.NextTick(false);
    return TRUE;
  }
  // reset fast mode
  if (SEqual(szCmdName, "slow")) {
    if (!Game.IsRunning) return FALSE;
    Game.FullSpeed = FALSE;
    Game.FrameSkip = 1;
    return TRUE;
  }

  if (SEqual(szCmdName, "nodebug")) {
    if (!Game.IsRunning) return FALSE;
    Game.Control.DoInput(CID_Set, new C4ControlSet(C4CVT_AllowDebug, false),
                         CDT_Decide);
    return TRUE;
  }

  if (SEqual(szCmdName, "msgboard")) {
    if (!Game.IsRunning) return FALSE;
    // get line cnt
    int32_t iLineCnt = BoundBy(atoi(pCmdPar), 0, 20);
    if (iLineCnt == 0)
      Game.GraphicsSystem.MessageBoard.ChangeMode(2);
    else if (iLineCnt == 1)
      Game.GraphicsSystem.MessageBoard.ChangeMode(0);
    else {
      Game.GraphicsSystem.MessageBoard.iLines = iLineCnt;
      Game.GraphicsSystem.MessageBoard.ChangeMode(1);
    }
    return TRUE;
  }

  // kick/activate/deactivate/observer
  if (SEqual(szCmdName, "activate") || SEqual(szCmdName, "deactivate") ||
      SEqual(szCmdName, "observer")) {
    if (!Game.Network.isEnabled() || !Game.Network.isHost()) {
      Log(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
      return FALSE;
    }
    // search for client
    C4Client *pClient = Game.Clients.getClientByName(pCmdPar);
    if (!pClient) {
      LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar);
      return FALSE;
    }
    // what to do?
    C4ControlClientUpdate *pCtrl = NULL;
    if (szCmdName[0] == 'a')  // activate
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, true);
    else if (szCmdName[0] == 'd' && !Game.Parameters.isLeague())  // deactivate
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, false);
    else if (szCmdName[0] == 'o' && !Game.Parameters.isLeague())  // observer
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_SetObserver);
    // perform it
    if (pCtrl)
      Game.Control.DoInput(CID_ClientUpdate, pCtrl, CDT_Sync);
    else
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
    return TRUE;
  }

  // control mode
  if (SEqual(szCmdName, "centralctrl") || SEqual(szCmdName, "decentralctrl") ||
      SEqual(szCmdName, "asyncctrl")) {
    if (!Game.Network.isEnabled() || !Game.Network.isHost()) {
      Log(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
      return FALSE;
    }
    if (Game.Parameters.isLeague() && *szCmdName == 'a') {
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
      return FALSE;
    }
    Game.Network.SetCtrlMode(
        *szCmdName == 'c' ? CNM_Central : *szCmdName == 'd' ? CNM_Decentral
                                                            : CNM_Async);
    return TRUE;
  }

  // show chart
  if (Game.IsRunning)
    if (SEqual(szCmdName, "chart")) return Game.ToggleChart();

  // custom command
  C4MessageBoardCommand *pCmd;
  if (Game.IsRunning)
    if (pCmd = GetCommand(szCmdName)) {
      StdStrBuf Script, CmdScript;
      // replace %player% by calling player number
      if (SSearch(pCmd->Script, "%player%")) {
        int32_t iLocalPlr = NO_OWNER;
        C4Player *pLocalPlr = Game.Players.GetLocalByIndex(0);
        if (pLocalPlr) iLocalPlr = pLocalPlr->Number;
        StdStrBuf sLocalPlr;
        sLocalPlr.Format("%d", iLocalPlr);
        CmdScript.Copy(pCmd->Script);
        CmdScript.Replace("%player%", sLocalPlr.getData());
      } else {
        CmdScript.Ref(pCmd->Script);
      }
      // insert parameters
      if (SSearch(CmdScript.getData(), "%d")) {
        // make sure it's a number by converting
        Script.Format(CmdScript.getData(), (int)atoi(pCmdPar));
      } else if (SSearch(CmdScript.getData(), "%s")) {
        // Unrestricted parameters?
        // That's kind of a security risk as it will allow anyone to execute
        // code
        switch (pCmd->eRestriction) {
          case C4MessageBoardCommand::C4MSGCMDR_Escaped: {
            // escape strings
            StdStrBuf Par;
            Par.Copy(pCmdPar);
            Par.EscapeString();
            // compose script
            Script.Format(CmdScript.getData(), Par.getData());
          } break;

          case C4MessageBoardCommand::C4MSGCMDR_Plain:
            // unescaped
            Script.Format(CmdScript.getData(), pCmdPar);
            break;

          case C4MessageBoardCommand::C4MSGCMDR_Identifier: {
            // only allow identifier-characters
            StdStrBuf Par;
            while (IsIdentifier(*pCmdPar) || isspace((unsigned char)*pCmdPar))
              Par.AppendChar(*pCmdPar++);
            // compose script
            Script.Format(CmdScript.getData(), Par.getData());
          } break;
        }
      } else
        Script = CmdScript.getData();
      // add script
      Game.Control.DoInput(CID_Script, new C4ControlScript(Script.getData()),
                           CDT_Decide);
      // ok
      return TRUE;
    }

  // unknown command
  StdStrBuf sErr;
  sErr.Format(LoadResStr("IDS_ERR_UNKNOWNCMD"), szCmdName);
  if (pLobby)
    pLobby->OnError(sErr.getData());
  else
    Log(sErr.getData());
  return FALSE;
}
void StdCompilerINIRead::CreateNameTree()
{
	FreeNameTree();
	// Create root node
	pName = pNameRoot = new NameNode();
	// No input? Stop
	if (!Buf) return;
	// Start scanning
	pPos = Buf.getPtr(0);
	while (*pPos)
	{
		// Go over whitespace
		int iIndent = 0;
		while (*pPos == ' ' || *pPos == '\t')
			{ pPos++; iIndent++; }
		// Name/Section?
		bool fSection = *pPos == '[' && isalpha((unsigned char)*(pPos+1));
		if (fSection || isalpha((unsigned char)*pPos))
		{
			// Treat values as if they had more indention
			// (so they become children of sections on the same level)
			if (!fSection) iIndent++; else pPos++;
			// Go up in tree structure if there is less indention
			while (pName->Parent && pName->Indent >= iIndent)
				pName = pName->Parent;
			// Copy name
			StdStrBuf Name;
			while (isalnum((unsigned char)*pPos) || *pPos == ' ' || *pPos == '_')
				Name.AppendChar(*pPos++);
			while (*pPos == ' ' || *pPos == '\t') pPos++;
			if ( *pPos != (fSection ? ']' : '=') )
				// Warn, ignore
				Warn(isprint((unsigned char)*pPos) ? "Unexpected character ('%c'): %s ignored" : "Unexpected character ('0x%02x'): %s ignored", unsigned(*pPos), fSection ? "section" : "value");
			else
			{
				pPos++;
				// Create new node
				NameNode *pPrev = pName->LastChild;
				pName =
				  pName->LastChild =
				    (pName->LastChild ? pName->LastChild->NextChild : pName->FirstChild) =
				      new NameNode(pName);
				pName->PrevChild = pPrev;
				pName->Name.Take(std::move(Name));
				pName->Pos = pPos;
				pName->Indent = iIndent;
				pName->Section = fSection;
				// Values don't have children (even if the indention looks like it)
				if (!fSection)
					pName = pName->Parent;
			}
		}
		// Skip line
		while (*pPos && (*pPos != '\n' && *pPos != '\r'))
			pPos++;
		while (*pPos == '\n' || *pPos == '\r')
			pPos++;
	}
	// Set pointer back
	pName = pNameRoot;
}
示例#13
0
文件: C4Update.cpp 项目: ev1313/yaC
BOOL C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp,
                           BOOL *fModified) {
    // (CAUTION: pGrp1 may be NULL - that means that there is no counterpart for
    // Grp2
    //           in the base group)

    // compare headers
    if (!pGrp1 || pGrp1->GetCreation() != pGrp2->GetCreation() ||
            pGrp1->GetOriginal() != pGrp2->GetOriginal() ||
            !SEqual(pGrp1->GetMaker(), pGrp2->GetMaker()) ||
            !SEqual(pGrp1->GetPassword(), pGrp2->GetPassword()))
        *fModified = TRUE;
    // set header
    pUpGrp->SetHead(*pGrp2);
    // compare entries
    char strItemName[_MAX_PATH], strItemName2[_MAX_PATH];
    StdStrBuf EntryList;
    strItemName[0] = strItemName2[0] = 0;
    pGrp2->ResetSearch();
    if (!*fModified) pGrp1->ResetSearch();
    int iChangedEntries = 0;
    while (pGrp2->FindNextEntry("*", strItemName, NULL, NULL, !!strItemName[0])) {
        // add to entry list
        if (!!EntryList) EntryList.AppendChar('|');
        EntryList.AppendFormat("%s=%d", strItemName, pGrp2->EntryTime(strItemName));
        // no modification detected yet? then check order
        if (!*fModified) {
            if (!pGrp1->FindNextEntry("*", strItemName2, NULL, NULL,
                                      !!strItemName2[0]))
                *fModified = TRUE;
            else if (!SEqual(strItemName, strItemName2))
                *fModified = TRUE;
        }

        // TODO: write DeleteEntries.txt

        // a child group?
        C4GroupEx ChildGrp2;
        if (ChildGrp2.OpenAsChild(pGrp2, strItemName)) {
            // open in Grp1
            C4Group *pChildGrp1 = new C4GroupEx();
            if (!pGrp1 || !pChildGrp1->OpenAsChild(pGrp1, strItemName)) {
                delete pChildGrp1;
                pChildGrp1 = NULL;
            }
            // open group for update data
            C4GroupEx UpdGroup;
            char strTempGroupName[_MAX_FNAME + 1];
            strTempGroupName[0] = 0;
            if (!UpdGroup.OpenAsChild(pUpGrp, strItemName)) {
                // create new group (may be temporary)
                // SCopy(GetCfg()->AtTempPath("~upd"), strTempGroupName, _MAX_FNAME);
                MakeTempFilename(strTempGroupName);
                if (!UpdGroup.Open(strTempGroupName, TRUE)) {
                    delete pChildGrp1;
                    WriteLog("Error: could not create temp group\n");
                    return FALSE;
                }
            }
            // do nested MkUp-search
            BOOL Modified = FALSE;
            BOOL fSuccess = MkUp(pChildGrp1, &ChildGrp2, &UpdGroup, &Modified);
            // sort & close
            extern const char **C4Group_SortList;
            UpdGroup.SortByList(C4Group_SortList, ChildGrp2.GetName());
            UpdGroup.Close(FALSE);
            // check entry times
            if (!pGrp1 ||
                    (pGrp1->EntryTime(strItemName) != pGrp2->EntryTime(strItemName)))
                Modified = TRUE;
            // add group (if modified)
            if (fSuccess && Modified) {
                if (strTempGroupName[0])
                    if (!pUpGrp->Move(strTempGroupName, strItemName)) {
                        WriteLog("Error: could not add modified group\n");
                        return FALSE;
                    }
                // copy core
                pUpGrp->SaveEntryCore(*pGrp2, strItemName);
                pUpGrp->SetSavedEntryCore(strItemName);
                // got a modification in a subgroup
                *fModified = TRUE;
                iChangedEntries++;
            } else
                // delete group (do not remove groups that existed before!)
                if (strTempGroupName[0])
                    if (remove(strTempGroupName))
                        if (rmdir(strTempGroupName)) {
                            WriteLog("Error: could not delete temporary directory\n");
                            return FALSE;
                        }
            delete pChildGrp1;
        } else {
            // compare them (size & crc32)
            if (!pGrp1 ||
                    pGrp1->EntrySize(strItemName) != pGrp2->EntrySize(strItemName) ||
                    pGrp1->EntryCRC32(strItemName) != pGrp2->EntryCRC32(strItemName)) {
                BOOL fCopied = FALSE;

                // save core (EntryCRC32 might set additional fields)
                pUpGrp->SaveEntryCore(*pGrp2, strItemName);

                // already in update grp?
                if (pUpGrp->EntryTime(strItemName) != pGrp2->EntryTime(strItemName) ||
                        pUpGrp->EntrySize(strItemName) != pGrp2->EntrySize(strItemName) ||
                        pUpGrp->EntryCRC32(strItemName) != pGrp2->EntryCRC32(strItemName)) {
                    // copy it
                    if (!C4Group_CopyEntry(pGrp2, pUpGrp, strItemName)) {
                        WriteLog("Error: could not add changed entry to update group\n");
                        return FALSE;
                    }
                    // set entry core
                    pUpGrp->SetSavedEntryCore(strItemName);
                    // modified...
                    *fModified = TRUE;
                    fCopied = TRUE;
                }
                iChangedEntries++;

                WriteLog("%s\\%s: update%s\n", pGrp2->GetFullName().getData(),
                         strItemName, fCopied ? "" : " (already in group)");
            }
        }
    }
    // write entries list (always)
    if (!pUpGrp->Add(C4CFN_UpdateEntries, EntryList, FALSE, TRUE)) {
        WriteLog("Error: could not save entry list!");
        return FALSE;
    }

    if (iChangedEntries > 0)
        WriteLog("%s: %d/%d changed (%s)\n", pGrp2->GetFullName().getData(),
                 iChangedEntries, pGrp2->EntryCount(),
                 *fModified ? "update" : "skip");

    // success
    return TRUE;
}