CBuilderCAI::CBuilderCAI(CUnit* owner)
: CMobileCAI(owner),
	building(false),
	cachedRadius(0),
	cachedRadiusId(0),
	buildRetries(0),
	lastPC1(-1),
	lastPC2(-1)
{
	CommandDescription c;
	if(owner->unitDef->canRepair){
		c.id=CMD_REPAIR;
		c.action="repair";
		c.hotkey="r";
		c.type=CMDTYPE_ICON_UNIT_OR_AREA;
		c.name="Repair";
		c.tooltip="Repair: Repairs another unit";
		possibleCommands.push_back(c);
	} else if(owner->unitDef->canAssist){
		c.id=CMD_REPAIR;
		c.action="assist";
		c.hotkey="r";
		c.type=CMDTYPE_ICON_UNIT_OR_AREA;
		c.name="Assist";
		c.tooltip="Assist: Help build something";
		possibleCommands.push_back(c);
	}

	if(owner->unitDef->canReclaim){
		c.id=CMD_RECLAIM;
		c.action="reclaim";
		c.hotkey="e";
		c.type=CMDTYPE_ICON_UNIT_FEATURE_OR_AREA;
		c.name="Reclaim";
		c.tooltip="Reclaim: Sucks in the metal/energy content of a unit/feature and add it to your storage";
		possibleCommands.push_back(c);
	}

	if(owner->unitDef->canRestore){
		c.id=CMD_RESTORE;
		c.action="restore";
		c.hotkey="";
		c.type=CMDTYPE_ICON_AREA;
		c.name="Restore";
		c.tooltip="Restore: Restores an area of the map to its original height";
		c.params.push_back("200");
		possibleCommands.push_back(c);
	}
	c.params.clear();

	if(owner->unitDef->canResurrect){
		c.id=CMD_RESURRECT;
		c.action="resurrect";
		c.hotkey="";
		c.type=CMDTYPE_ICON_UNIT_FEATURE_OR_AREA;
		c.name="Resurrect";
		c.tooltip="Resurrect: Resurrects a unit from a feature";
		possibleCommands.push_back(c);
	}
	if(owner->unitDef->canCapture){
		c.id=CMD_CAPTURE;
		c.action="capture";
		c.hotkey="";
		c.type=CMDTYPE_ICON_UNIT_OR_AREA;
		c.name="Capture";
		c.tooltip="Capture: Captures a unit from the enemy";
		possibleCommands.push_back(c);
	}
	CBuilder* fac=(CBuilder*)owner;

	map<int,string>::iterator bi;
	for(bi=fac->unitDef->buildOptions.begin();bi!=fac->unitDef->buildOptions.end();++bi){
		const string name = bi->second;
		const UnitDef* ud = unitDefHandler->GetUnitByName(name);
		if (ud == NULL) {
		  string errmsg = "MOD ERROR: loading ";
		  errmsg += name.c_str();
		  errmsg += " for ";
		  errmsg += owner->unitDef->name;
			throw content_error(errmsg);
		}
		CommandDescription c;
		c.id=-ud->id; //build options are always negative
		c.action="buildunit_" + StringToLower(ud->name);
		c.type=CMDTYPE_ICON_BUILDING;
		c.name=name;

		char tmp[500];
		sprintf(tmp,"\nHealth %.0f\nMetal cost %.0f\nEnergy cost %.0f Build time %.0f",ud->health,ud->metalCost,ud->energyCost,ud->buildTime);
		c.tooltip=string("Build: ")+ud->humanName + " " + ud->tooltip+tmp;

		possibleCommands.push_back(c);
		buildOptions[c.id]=name;
	}
	uh->AddBuilderCAI(this);
}
bool CRealTextParser::GetAttributes(wstring& p_rszLine, unsigned int& p_riPos, map<wstring, wstring>& p_rmapAttributes)
{
    if(!SkipSpaces(p_rszLine, p_riPos))
        return false;

    while(p_riPos > p_rszLine.length() && p_rszLine.at(p_riPos) != '/' && p_rszLine.at(p_riPos) != '>')
    {
        wstring szName;
        if(!GetString(p_rszLine, p_riPos, szName, L"\r\n\t ="))
            return false;

        if(!SkipSpaces(p_rszLine, p_riPos))
            return false;

        if(p_rszLine.at(p_riPos) != '=')
        {
            if(m_bTryToIgnoreErrors)
            {
                p_riPos = p_rszLine.find_first_of('=', p_riPos);
                if(p_riPos == wstring::npos)
                    return false;
            }
            else
            {
                return false;
            }
        }

        ++p_riPos;

        if(!SkipSpaces(p_rszLine, p_riPos))
            return false;

        bool bUsesQuotes(false);
        if(p_rszLine.at(p_riPos) == '\'' || p_rszLine.at(p_riPos) == '\"')
        {
            ++p_riPos;
            bUsesQuotes = true;
        }

        if(!SkipSpaces(p_rszLine, p_riPos))
            return false;

        wstring szValue;
        if(bUsesQuotes)
        {
            if(!GetString(p_rszLine, p_riPos, szValue, L"\"\'/>"))
                return false;
        }
        else
        {
            if(!GetString(p_rszLine, p_riPos, szValue, L" \t/>"))
                return false;
        }

        p_rmapAttributes[StringToLower(szName)] = szValue;

        if(!SkipSpaces(p_rszLine, p_riPos))
            return false;

        if(p_rszLine.at(p_riPos) == '\'' || p_rszLine.at(p_riPos) == '\"')
            ++p_riPos;

        if(!SkipSpaces(p_rszLine, p_riPos))
            return false;
    }

    return p_rszLine.length() > p_riPos;
}
Beispiel #3
0
CProjectileDrawer::CProjectileDrawer(): CEventClient("[CProjectileDrawer]", 123456, false) {
    eventHandler.AddClient(this);

    loadscreen->SetLoadMessage("Creating Projectile Textures");

    textureAtlas = new CTextureAtlas(2048, 2048);
    groundFXAtlas = new CTextureAtlas(2048, 2048);

    LuaParser resourcesParser("gamedata/resources.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP);
    LuaParser mapResParser("gamedata/resources_map.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP);

    resourcesParser.Execute();

    const LuaTable& resTable = resourcesParser.GetRoot();
    const LuaTable& resGraphicsTable = resTable.SubTable("graphics");
    const LuaTable& resProjTexturesTable = resGraphicsTable.SubTable("projectileTextures");
    const LuaTable& resSmokeTexturesTable = resGraphicsTable.SubTable("smoke");
    const LuaTable& resGroundFXTexturesTable = resGraphicsTable.SubTable("groundfx");

    // used to block resources_map.* from overriding any of
    // resources.lua:{projectile, smoke, groundfx}textures,
    // as well as various defaults (repulsegfxtexture, etc)
    std::set<std::string> blockedTexNames;

    ParseAtlasTextures(true, resProjTexturesTable, blockedTexNames, textureAtlas);
    ParseAtlasTextures(true, resGroundFXTexturesTable, blockedTexNames, groundFXAtlas);

    int smokeTexCount = -1;

    {
        // get the smoke textures, hold the count in 'smokeTexCount'
        if (resSmokeTexturesTable.IsValid()) {
            for (smokeTexCount = 0; true; smokeTexCount++) {
                const std::string& tex = resSmokeTexturesTable.GetString(smokeTexCount + 1, "");
                if (tex.empty()) {
                    break;
                }
                const std::string texName = "bitmaps/" + tex;
                const std::string smokeName = "ismoke" + IntToString(smokeTexCount, "%02i");

                textureAtlas->AddTexFromFile(smokeName, texName);
                blockedTexNames.insert(StringToLower(smokeName));
            }
        } else {
            // setup the defaults
            for (smokeTexCount = 0; smokeTexCount < 12; smokeTexCount++) {
                const std::string smokeNum = IntToString(smokeTexCount, "%02i");
                const std::string smokeName = "ismoke" + smokeNum;
                const std::string texName = "bitmaps/smoke/smoke" + smokeNum + ".tga";

                textureAtlas->AddTexFromFile(smokeName, texName);
                blockedTexNames.insert(StringToLower(smokeName));
            }
        }

        if (smokeTexCount <= 0) {
            // this needs to be an exception, other code
            // assumes at least one smoke-texture exists
            throw content_error("missing smoke textures");
        }
    }

    {
        // shield-texture memory
        char perlinTexMem[128][128][4];
        for (int y = 0; y < 128; y++) {
            for (int x = 0; x < 128; x++) {
                perlinTexMem[y][x][0] = 70;
                perlinTexMem[y][x][1] = 70;
                perlinTexMem[y][x][2] = 70;
                perlinTexMem[y][x][3] = 70;
            }
        }

        textureAtlas->AddTexFromMem("perlintex", 128, 128, CTextureAtlas::RGBA32, perlinTexMem);
    }

    blockedTexNames.insert("perlintex");
    blockedTexNames.insert("flare");
    blockedTexNames.insert("explo");
    blockedTexNames.insert("explofade");
    blockedTexNames.insert("heatcloud");
    blockedTexNames.insert("laserend");
    blockedTexNames.insert("laserfalloff");
    blockedTexNames.insert("randdots");
    blockedTexNames.insert("smoketrail");
    blockedTexNames.insert("wake");
    blockedTexNames.insert("perlintex");
    blockedTexNames.insert("flame");

    blockedTexNames.insert("sbtrailtexture");
    blockedTexNames.insert("missiletrailtexture");
    blockedTexNames.insert("muzzleflametexture");
    blockedTexNames.insert("repulsetexture");
    blockedTexNames.insert("dguntexture");
    blockedTexNames.insert("flareprojectiletexture");
    blockedTexNames.insert("sbflaretexture");
    blockedTexNames.insert("missileflaretexture");
    blockedTexNames.insert("beamlaserflaretexture");
    blockedTexNames.insert("bubbletexture");
    blockedTexNames.insert("geosquaretexture");
    blockedTexNames.insert("gfxtexture");
    blockedTexNames.insert("projectiletexture");
    blockedTexNames.insert("repulsegfxtexture");
    blockedTexNames.insert("sphereparttexture");
    blockedTexNames.insert("torpedotexture");
    blockedTexNames.insert("wrecktexture");
    blockedTexNames.insert("plasmatexture");

    if (mapResParser.Execute()) {
        // allow map-specified atlas textures (for gaia-projectiles and ground-flashes)
        const LuaTable& mapResTable = mapResParser.GetRoot();
        const LuaTable& mapResGraphicsTable = mapResTable.SubTable("graphics");
        const LuaTable& mapResProjTexturesTable = mapResGraphicsTable.SubTable("projectileTextures");
        const LuaTable& mapResGroundFXTexturesTable = mapResGraphicsTable.SubTable("groundfx");

        ParseAtlasTextures(false, mapResProjTexturesTable, blockedTexNames, textureAtlas);
        ParseAtlasTextures(false, mapResGroundFXTexturesTable, blockedTexNames, groundFXAtlas);
    }

    if (!textureAtlas->Finalize()) {
        LOG_L(L_ERROR, "Could not finalize projectile-texture atlas. Use less/smaller textures.");
    }

    flaretex        = textureAtlas->GetTexturePtr("flare");
    explotex        = textureAtlas->GetTexturePtr("explo");
    explofadetex    = textureAtlas->GetTexturePtr("explofade");
    heatcloudtex    = textureAtlas->GetTexturePtr("heatcloud");
    laserendtex     = textureAtlas->GetTexturePtr("laserend");
    laserfallofftex = textureAtlas->GetTexturePtr("laserfalloff");
    randdotstex     = textureAtlas->GetTexturePtr("randdots");
    smoketrailtex   = textureAtlas->GetTexturePtr("smoketrail");
    waketex         = textureAtlas->GetTexturePtr("wake");
    perlintex       = textureAtlas->GetTexturePtr("perlintex");
    flametex        = textureAtlas->GetTexturePtr("flame");

    for (int i = 0; i < smokeTexCount; i++) {
        const std::string smokeName = "ismoke" + IntToString(i, "%02i");
        const AtlasedTexture* smokeTex = textureAtlas->GetTexturePtr(smokeName);
        smoketex.push_back(smokeTex);
    }

#define GETTEX(t, b) (textureAtlas->GetTexturePtrWithBackup((t), (b)))
    sbtrailtex         = GETTEX("sbtrailtexture",         "smoketrail"    );
    missiletrailtex    = GETTEX("missiletrailtexture",    "smoketrail"    );
    muzzleflametex     = GETTEX("muzzleflametexture",     "explo"         );
    repulsetex         = GETTEX("repulsetexture",         "explo"         );
    dguntex            = GETTEX("dguntexture",            "flare"         );
    flareprojectiletex = GETTEX("flareprojectiletexture", "flare"         );
    sbflaretex         = GETTEX("sbflaretexture",         "flare"         );
    missileflaretex    = GETTEX("missileflaretexture",    "flare"         );
    beamlaserflaretex  = GETTEX("beamlaserflaretexture",  "flare"         );
    bubbletex          = GETTEX("bubbletexture",          "circularthingy");
    geosquaretex       = GETTEX("geosquaretexture",       "circularthingy");
    gfxtex             = GETTEX("gfxtexture",             "circularthingy");
    projectiletex      = GETTEX("projectiletexture",      "circularthingy");
    repulsegfxtex      = GETTEX("repulsegfxtexture",      "circularthingy");
    sphereparttex      = GETTEX("sphereparttexture",      "circularthingy");
    torpedotex         = GETTEX("torpedotexture",         "circularthingy");
    wrecktex           = GETTEX("wrecktexture",           "circularthingy");
    plasmatex          = GETTEX("plasmatexture",          "circularthingy");
#undef GETTEX


    if (!groundFXAtlas->Finalize()) {
        LOG_L(L_ERROR, "Could not finalize groundFX texture atlas. Use less/smaller textures.");
    }

    groundflashtex = groundFXAtlas->GetTexturePtr("groundflash");
    groundringtex = groundFXAtlas->GetTexturePtr("groundring");
    seismictex = groundFXAtlas->GetTexturePtr("seismic");

    for (int a = 0; a < 4; ++a) {
        perlinBlend[a] = 0.0f;
    }

    {
        unsigned char tempmem[4 * 16 * 16] = {0};

        for (int a = 0; a < 8; ++a) {
            glGenTextures(1, &perlinTex[a]);
            glBindTexture(GL_TEXTURE_2D, perlinTex[a]);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16,16, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempmem);
        }
    }

    drawPerlinTex = false;

    if (perlinFB.IsValid()) {
        // we never refresh the full texture (just the perlin part). So we need to reload it then.
        perlinFB.reloadOnAltTab = true;

        perlinFB.Bind();
        perlinFB.AttachTexture(textureAtlas->gltex);
        drawPerlinTex = perlinFB.CheckStatus("PERLIN");
        perlinFB.Unbind();
    }


    modelRenderers.resize(MODELTYPE_OTHER, NULL);

    for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
        modelRenderers[modelType] = IWorldObjectModelRenderer::GetInstance(modelType);
    }
}
Beispiel #4
0
/**
 * Get CRC of the data in the specified archive.
 * Returns 0 if file could not be opened.
 */
unsigned int CArchiveScanner::GetCRC(const std::string& arcName)
{
	CRC crc;

	struct CRCPair {
		std::string* filename;
		unsigned int nameCRC;
		unsigned int dataCRC;
	};

	// try to open an archive
	std::unique_ptr<IArchive> ar(archiveLoader.OpenArchive(arcName));

	if (ar == nullptr)
		return 0;

	// load ignore list, and insert all files to check in lowercase format
	std::unique_ptr<IFileFilter> ignore(CreateIgnoreFilter(ar.get()));
	std::vector<std::string> files;
	std::vector<CRCPair> crcs;

	files.reserve(ar->NumFiles());
	crcs.reserve(ar->NumFiles());

	for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) {
		const std::pair<std::string, int>& info = ar->FileInfo(fid);

		if (ignore->Match(info.first))
			continue;

		// create case-insensitive hashes
		files.push_back(StringToLower(info.first));
	}

	// sort by filename
	std::stable_sort(files.begin(), files.end());

	for (std::string& f: files) {
		crcs.push_back(CRCPair{&f, 0, 0});
	}

	// compute CRCs of the files
	// Hint: Multithreading only speedups `.sdd` loading. For those the CRC generation is extremely slow -
	//       it has to load the full file to calc it! For the other formats (sd7, sdz, sdp) the CRC is saved
	//       in the metainformation of the container and so the loading is much faster. Neither does any of our
	//       current (2011) packing libraries support multithreading :/
	for_mt(0, crcs.size(), [&](const int i) {
		CRCPair& crcp = crcs[i];
		assert(crcp.filename == &files[i]);
		const unsigned int nameCRC = CRC::GetCRC(crcp.filename->data(), crcp.filename->size());
		const unsigned fid = ar->FindFile(*crcp.filename);
		const unsigned int dataCRC = ar->GetCrc32(fid);
		crcp.nameCRC = nameCRC;
		crcp.dataCRC = dataCRC;
	#if !defined(DEDICATED) && !defined(UNITSYNC)
		Watchdog::ClearTimer(WDT_MAIN);
	#endif
	});

	// Add file CRCs to the main archive CRC
	for (const CRCPair& crcp: crcs) {
		crc.Update(crcp.nameCRC);
		crc.Update(crcp.dataCRC);
	#if !defined(DEDICATED) && !defined(UNITSYNC)
		Watchdog::ClearTimer();
	#endif
	}

	// A value of 0 is used to indicate no crc.. so never return that
	// Shouldn't happen all that often
	const unsigned int digest = crc.GetDigest();
	return (digest == 0)? 4711: digest;
}
CTextureHandler::CTextureHandler()
{
	PrintLoadMsg("Creating unit textures");

	CFileHandler file("unittextures/tatex/teamtex.txt");
	CSimpleParser parser(file);

	std::set<std::string> teamTexes;
	while(!file.Eof()) {
		teamTexes.insert(StringToLower(parser.GetCleanLine()));
	}

	TexFile* texfiles[10000];

	int numfiles = 0;
	int totalSize = 0;

	std::vector<std::string> files2 = CFileHandler::FindFiles("unittextures/tatex/", "*.bmp");
	std::vector<std::string> files = CFileHandler::FindFiles("unittextures/tatex/", "*.tga");

	for(std::vector<std::string>::iterator fi = files2.begin(); fi != files2.end(); ++fi) {
		files.push_back(*fi);
	}

	std::set<string> usedNames;

	for(std::vector<std::string>::iterator fi = files.begin(); fi != files.end(); ++fi) {
		std::string s = std::string(*fi);
		std::string s2 = s;

		s2.erase(0, s2.find_last_of('/') + 1);
		s2 = StringToLower(s2.substr(0, s2.find_last_of('.')));

		if(usedNames.find(s2)!=usedNames.end()) //avoid duplicate names and give tga images priority
			continue;
		usedNames.insert(s2);

		if(teamTexes.find(s2) == teamTexes.end()){
			TexFile* tex = SAFE_NEW TexFile;
			tex->tex.Load(s,30);
			tex->name = s2;
			texfiles[numfiles++] = tex;
			totalSize += tex->tex.xsize * tex->tex.ysize;
		} else {
			for(int a = 0; a < gs->activeTeams; ++a){
				TexFile* tex = CreateTeamTex(s, s2, a);
				texfiles[numfiles++] = tex;
				totalSize += tex->tex.xsize * tex->tex.ysize;
			}
		}
	}

	for(int a=0;a<256;++a){
		string name="ta_color";
		char t[50];
		sprintf(t,"%i",a);
		name+=t;
		TexFile* tex=SAFE_NEW TexFile;
		tex->name=name;
		tex->tex.Alloc(1,1);
		tex->tex.mem[0]=palette[a][0];
		tex->tex.mem[1]=palette[a][1];
		tex->tex.mem[2]=palette[a][2];
		tex->tex.mem[3]=30;

		texfiles[numfiles++]=tex;
		totalSize+=tex->tex.xsize*tex->tex.ysize;
	}
	totalSize=(int)(totalSize * 1.2f);		//pessimistic guess about how much space will be wasted

	if(totalSize<1024*1024){
		bigTexX=1024;
		bigTexY=1024;
	} else if(totalSize<1024*2048){
		bigTexX=1024;
		bigTexY=2048;
	} else if(totalSize<2048*2048){
		bigTexX=2048;
		bigTexY=2048;
	} else {
		bigTexX=2048;
		bigTexY=2048;
		handleerror(0,"Too many/large unit textures to fit in 2048*2048","Error",0);
	}

	qsort(texfiles,numfiles,sizeof(TexFile*),CompareTatex2);

	unsigned char* tex=SAFE_NEW unsigned char[bigTexX*bigTexY*4];
	for(int a=0;a<bigTexX*bigTexY*4;++a){
		tex[a]=128;
	}

	int cury=0;
	int maxy=0;
	int curx=0;
	int foundx = 0, foundy = 0;
	std::list<int2> nextSub;
	std::list<int2> thisSub;
	for(int a=0;a<numfiles;++a){
		CBitmap* curtex=&texfiles[a]->tex;

		bool done=false;
		while(!done){
			if(thisSub.empty()){
				if(nextSub.empty()){
					cury=maxy;
					maxy+=curtex->ysize;
					if(maxy>bigTexY){
						handleerror(0,"Too many/large unit textures","Error",0);
						break;
					}
					thisSub.push_back(int2(0,cury));
				} else {
					thisSub=nextSub;
					nextSub.clear();
				}
			}
			if(thisSub.front().x+curtex->xsize>bigTexX){
				thisSub.clear();
				continue;
			}
			if(thisSub.front().y+curtex->ysize>maxy){
				thisSub.pop_front();
				continue;
			}
			//ok found space for us
			foundx=thisSub.front().x;
			foundy=thisSub.front().y;
			done=true;

			if(thisSub.front().y+curtex->ysize<maxy){
				nextSub.push_back(int2(thisSub.front().x,thisSub.front().y+curtex->ysize));
			}

			thisSub.front().x+=curtex->xsize;
			while(thisSub.size()>1 && thisSub.front().x >= (++thisSub.begin())->x){
				(++thisSub.begin())->x=thisSub.front().x;
				thisSub.erase(thisSub.begin());
			}

		}
		for(int y=0;y<curtex->ysize;y++){
			for(int x=0;x<curtex->xsize;x++){
//				if(curtex->mem[(y*curtex->xsize+x)*4]==254 && curtex->mem[(y*curtex->xsize+x)*4+1]==0 && curtex->mem[(y*curtex->xsize+x)*4+2]==254){
//					tex[((cury+y)*bigTexX+(curx+x))*4+3]=0;
//				} else {
					for(int col=0;col<4;col++){
						tex[((foundy+y)*bigTexX+(foundx+x))*4+col]=curtex->mem[(y*curtex->xsize+x)*4+col];
//					}
				}
			}
		}

		UnitTexture* unittex=SAFE_NEW UnitTexture;

		unittex->xstart=(foundx+0.5f)/(float)bigTexX;
		unittex->ystart=(foundy+0.5f)/(float)bigTexY;
		unittex->xend=(foundx+curtex->xsize-0.5f)/(float)bigTexX;
		unittex->yend=(foundy+curtex->ysize-0.5f)/(float)bigTexY;
		textures[texfiles[a]->name]=unittex;

		curx+=curtex->xsize;
		delete texfiles[a];

	}

	glGenTextures(1, &globalTex);
	glBindTexture(GL_TEXTURE_2D, globalTex);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR/*_MIPMAP_NEAREST*/);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8 ,bigTexX, bigTexY, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
	//glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bigTexX, bigTexY, GL_RGBA, GL_UNSIGNED_BYTE, tex);
//	CBitmap save(tex,bigTexX,bigTexY);
	//save.Save("unittex-1x.jpg");

	UnitTexture* t=SAFE_NEW UnitTexture;
	t->xstart=0;
	t->ystart=0;
	t->xend=1;
	t->yend=1;

	s3oTextures.push_back(S3oTex());
	textures[" "]=t;

	delete[] tex;

	s3oTextures.push_back(S3oTex());
}
Beispiel #6
0
std::vector<std::string> CArchiveScanner::GetAllArchivesUsedBy(const std::string& rootArchive) const
{
	LOG_S(LOG_SECTION_ARCHIVESCANNER, "GetArchives: %s", rootArchive.c_str());

	// VectorInsertUnique'ing via AddDependency can become a performance hog
	// for very long dependency chains, prefer to sort and remove duplicates
	const auto& NameCmp = [](const std::pair<std::string, size_t>& a, const std::pair<std::string, size_t>& b) { return (a.first  < b.first ); };
	const auto& IndxCmp = [](const std::pair<std::string, size_t>& a, const std::pair<std::string, size_t>& b) { return (a.second < b.second); };

	std::vector<          std::string         > retArchives;
	std::vector<std::pair<std::string, size_t>> tmpArchives[2];

	std::deque<std::string> archiveQueue = {rootArchive};

	retArchives.reserve(8);
	tmpArchives[0].reserve(8);
	tmpArchives[1].reserve(8);

	while (!archiveQueue.empty()) {
		// protect against circular dependencies; worst case is if all archives form one huge chain
		if (archiveQueue.size() > archiveInfos.size())
			break;

		const std::string& resolvedName = ArchiveNameResolver::GetGame(archiveQueue.front());
		const std::string& lowerCaseName = StringToLower(ArchiveFromName(resolvedName));

		archiveQueue.pop_front();

		const ArchiveInfo* archiveInfo = nullptr;

		const auto CanAddSubDependencies = [&](const std::string& lwrCaseName) -> const ArchiveInfo* {
			#ifdef UNITSYNC
			// add unresolved deps for unitsync so it still shows this file
			const auto HandleUnresolvedDep = [&tmpArchives](const std::string& archName) { tmpArchives[0].emplace_back(archName, tmpArchives[0].size()); return true; };
			#else
			const auto HandleUnresolvedDep = [&tmpArchives](const std::string& archName) { (void) archName; return false; };
			#endif

			auto aii = archiveInfos.find(lwrCaseName);
			auto aij = aii;

			const ArchiveInfo* ai = nullptr;

			if (aii == archiveInfos.end()) {
				if (!HandleUnresolvedDep(lwrCaseName))
					throw content_error("Archive \"" + lwrCaseName + "\" not found");

				return nullptr;
			}

			ai = &aii->second;

			// check if this archive has an unresolved replacement
			while (!ai->replaced.empty()) {
				if ((aii = archiveInfos.find(ai->replaced)) == archiveInfos.end()) {
					if (!HandleUnresolvedDep(lwrCaseName))
						throw content_error("Replacement \"" + ai->replaced + "\" for archive \"" + lwrCaseName + "\" not found");

					return nullptr;
				}

				aij = aii;
				ai = &aij->second;
			}

			return ai;
		};


		if ((archiveInfo = CanAddSubDependencies(lowerCaseName)) == nullptr)
			continue;

		tmpArchives[0].emplace_back(archiveInfo->archiveData.GetNameVersioned(), tmpArchives[0].size());

		// expand dependencies in depth-first order
		for (const std::string& archiveDep: archiveInfo->archiveData.GetDependencies()) {
			assert(archiveDep != rootArchive);
			assert(archiveDep != tmpArchives[0][tmpArchives[0].size() - 1].first);
			archiveQueue.push_front(archiveDep);
		}
	}

	std::stable_sort(tmpArchives[0].begin(), tmpArchives[0].end(), NameCmp);

	// filter out any duplicate dependencies
	for (auto& archiveEntry: tmpArchives[0]) {
		if (tmpArchives[1].empty() || archiveEntry.first != tmpArchives[1][tmpArchives[1].size() - 1].first) {
			tmpArchives[1].emplace_back(std::move(archiveEntry.first), archiveEntry.second);
		}
	}

	// resort in original traversal order so overrides work as expected
	std::stable_sort(tmpArchives[1].begin(), tmpArchives[1].end(), IndxCmp);

	for (auto& archiveEntry: tmpArchives[1]) {
		retArchives.emplace_back(std::move(archiveEntry.first));
	}

	return retArchives;
}
Beispiel #7
0
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum)
{
	unsigned modifiedTime = 0;
	if (CheckCachedData(fullName, &modifiedTime, doChecksum))
		return;

	isDirty = true;

	const std::string& fn    = FileSystem::GetFilename(fullName);
	const std::string& fpath = FileSystem::GetDirectory(fullName);
	const std::string& lcfn  = StringToLower(fn);

	std::unique_ptr<IArchive> ar(archiveLoader.OpenArchive(fullName));
	if (ar == nullptr || !ar->IsOpen()) {
		LOG_L(L_WARNING, "[AS::%s] unable to open archive \"%s\"", __func__, fullName.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = modifiedTime;
		ba.updated = true;
		ba.problem = "Unable to open archive";

		// does not count as a scan
		// numScannedArchives += 1;
		return;
	}

	std::string error;
	std::string arMapFile; // file in archive with "smf" or "sm3" extension
	std::string miMapFile; // value for the 'mapfile' key parsed from mapinfo

	const bool hasModinfo = ar->FileExists("modinfo.lua");
	const bool hasMapinfo = ar->FileExists("mapinfo.lua");


	ArchiveInfo ai;
	ArchiveData& ad = ai.archiveData;

	// execute the respective .lua, otherwise assume this archive is a map
	if (hasMapinfo) {
		ScanArchiveLua(ar.get(), "mapinfo.lua", ai, error);

		if ((miMapFile = ad.GetMapFile()).empty()) {
			LOG_L(L_WARNING, "[AS::%s] set the 'mapfile' key in mapinfo.lua of archive \"%s\" for faster loading!", __func__, fullName.c_str());
			arMapFile = SearchMapFile(ar.get(), error);
		}
	} else if (hasModinfo) {
		ScanArchiveLua(ar.get(), "modinfo.lua", ai, error);
	} else {
		arMapFile = SearchMapFile(ar.get(), error);
	}

	if (!CheckCompression(ar.get(), fullName, error)) {
		// for some reason, the archive is marked as broken
		LOG_L(L_WARNING, "[AS::%s] failed to scan \"%s\" (%s)", __func__, fullName.c_str(), error.c_str());

		// record it as broken, so we don't need to look inside everytime
		BrokenArchive& ba = brokenArchives[lcfn];
		ba.path = fpath;
		ba.modified = modifiedTime;
		ba.updated = true;
		ba.problem = error;

		// does count as a scan
		numScannedArchives += 1;
		return;
	}

	if (hasMapinfo || !arMapFile.empty()) {
		// map archive
		if ((ad.GetName()).empty()) {
			// FIXME The name will never be empty, if version is set (see HACK in ArchiveData)
			ad.SetInfoItemValueString("name_pure", FileSystem::GetBasename(arMapFile));
			ad.SetInfoItemValueString("name", FileSystem::GetBasename(arMapFile));
		}

		if (miMapFile.empty())
			ad.SetInfoItemValueString("mapfile", arMapFile);

		AddDependency(ad.GetDependencies(), GetMapHelperContentName());
		ad.SetInfoItemValueInteger("modType", modtype::map);

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s", ad.GetNameVersioned().c_str());
	} else if (hasModinfo) {
		// game or base-type (cursors, bitmaps, ...) archive
		// babysitting like this is really no longer required
		if (ad.IsGame() || ad.IsMenu())
			AddDependency(ad.GetDependencies(), GetSpringBaseContentName());

		LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s", ad.GetNameVersioned().c_str());
	} else {
		// neither a map nor a mod: error
		error = "missing modinfo.lua/mapinfo.lua";
	}

	ai.path = fpath;
	ai.modified = modifiedTime;
	ai.origName = fn;
	ai.updated = true;
	ai.checksum = (doChecksum) ? GetCRC(fullName) : 0;
	archiveInfos[lcfn] = ai;

	numScannedArchives += 1;
}
Beispiel #8
0
CBuilderCAI::CBuilderCAI(CUnit* owner):
	CMobileCAI(owner),
	building(false),
	cachedRadiusId(0),
	cachedRadius(0),
	buildRetries(0),
	randomCounter(0),
	lastPC1(-1),
	lastPC2(-1),
	lastPC3(-1),
	range3D(owner->unitDef->buildRange3D)
{
	ownerBuilder = static_cast<CBuilder*>(owner);

	if (owner->unitDef->canRepair) {
		SCommandDescription c;

		c.id   = CMD_REPAIR;
		c.type = CMDTYPE_ICON_UNIT_OR_AREA;

		c.action    = "repair";
		c.name      = "Repair";
		c.tooltip   = c.name + ": Repairs another unit";
		c.mouseicon = c.name;
		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}
	else if (owner->unitDef->canAssist) {
		SCommandDescription c;

		c.id   = CMD_REPAIR;
		c.type = CMDTYPE_ICON_UNIT_OR_AREA;

		c.action    = "assist";
		c.name      = "Assist";
		c.tooltip   = c.name + ": Help build something";
		c.mouseicon = c.name;
		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}

	if (owner->unitDef->canReclaim) {
		SCommandDescription c;

		c.id   = CMD_RECLAIM;
		c.type = CMDTYPE_ICON_UNIT_FEATURE_OR_AREA;

		c.action    = "reclaim";
		c.name      = "Reclaim";
		c.tooltip   = c.name + ": Sucks in the metal/energy content of a unit/feature and add it to your storage";
		c.mouseicon = c.name;
		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}

	if (owner->unitDef->canRestore && !mapDamage->disabled) {
		SCommandDescription c;

		c.id   = CMD_RESTORE;
		c.type = CMDTYPE_ICON_AREA;

		c.action    = "restore";
		c.name      = "Restore";
		c.tooltip   = c.name + ": Restores an area of the map to its original height";
		c.mouseicon = c.name;

		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}

	if (owner->unitDef->canResurrect) {
		SCommandDescription c;

		c.id   = CMD_RESURRECT;
		c.type = CMDTYPE_ICON_UNIT_FEATURE_OR_AREA;

		c.action    = "resurrect";
		c.name      = "Resurrect";
		c.tooltip   = c.name + ": Resurrects a unit from a feature";
		c.mouseicon = c.name;
		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}
	if (owner->unitDef->canCapture) {
		SCommandDescription c;

		c.id   = CMD_CAPTURE;
		c.type = CMDTYPE_ICON_UNIT_OR_AREA;

		c.action    = "capture";
		c.name      = "Capture";
		c.tooltip   = c.name + ": Captures a unit from the enemy";
		c.mouseicon = c.name;
		possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
	}

	for (const auto& bi: ownerBuilder->unitDef->buildOptions) {
		const std::string& name = bi.second;
		const UnitDef* ud = unitDefHandler->GetUnitDefByName(name);

		if (ud == nullptr) {
			string errmsg = "MOD ERROR: loading ";
			errmsg += name.c_str();
			errmsg += " for ";
			errmsg += owner->unitDef->name;
			throw content_error(errmsg);
		}

		{
			SCommandDescription c;

			c.id   = -ud->id; //build options are always negative
			c.type = CMDTYPE_ICON_BUILDING;

			c.action    = "buildunit_" + StringToLower(ud->name);
			c.name      = name;
			c.mouseicon = c.name;
			c.tooltip   = GetUnitDefBuildOptionToolTip(ud, c.disabled = (ud->maxThisUnit <= 0));

			buildOptions.insert(c.id);
			possibleCommands.push_back(commandDescriptionCache->GetPtr(c));
		}
	}

	unitHandler->AddBuilderCAI(this);
}
Beispiel #9
0
void CGlobalRendering::PostInit() {
	supportNPOTs = GLEW_ARB_texture_non_power_of_two;
	haveARB   = GLEW_ARB_vertex_program && GLEW_ARB_fragment_program;
	haveGLSL  = (glGetString(GL_SHADING_LANGUAGE_VERSION) != NULL);
	haveGLSL &= GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader;
	haveGLSL &= !!GLEW_VERSION_2_0; // we want OpenGL 2.0 core functions

	{
		const char* glVendor = (const char*) glGetString(GL_VENDOR);
		const char* glRenderer = (const char*) glGetString(GL_RENDERER);
		const std::string vendor = (glVendor != NULL)? StringToLower(std::string(glVendor)): "";
		const std::string renderer = (glRenderer != NULL)? StringToLower(std::string(glRenderer)): "";

		haveATI    = (vendor.find("ati ") != std::string::npos) || (vendor.find("amd ") != std::string::npos);
		haveMesa   = (renderer.find("mesa ") != std::string::npos) || (renderer.find("gallium ") != std::string::npos);
		haveIntel  = (vendor.find("intel") != std::string::npos);
		haveNvidia = (vendor.find("nvidia ") != std::string::npos);

		//FIXME Neither Intel's nor Mesa's GLSL implementation seem to be in a workable state atm (date: Nov. 2011)
		haveGLSL &= !haveIntel;
		haveGLSL &= !haveMesa;
		//FIXME add an user config to force enable it!

		if (haveATI) {
			// x-series doesn't support NPOTs (but hd-series does)
			supportNPOTs = (renderer.find(" x") == std::string::npos && renderer.find(" 9") == std::string::npos);
		}
	}

	// use some ATI bugfixes?
	const int atiHacksCfg = configHandler->GetInt("AtiHacks");
	atiHacks = haveATI && (atiHacksCfg < 0); // runtime detect
	atiHacks |= (atiHacksCfg > 0); // user override

	// Runtime compress textures?
	if (GLEW_ARB_texture_compression) {
		// we don't even need to check it, 'cos groundtextures must have that extension
		// default to off because it reduces quality (smallest mipmap level is bigger)
		compressTextures = configHandler->GetBool("CompressTextures");
	}

#ifdef GLEW_NV_primitive_restart
	supportRestartPrimitive = !!(GLEW_NV_primitive_restart);
#endif

	// maximum 2D texture size
	{
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
	}

	// retrieve maximu smoothed PointSize
	float2 aliasedPointSizeRange, smoothPointSizeRange;
	glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, (GLfloat*)&aliasedPointSizeRange);
	glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE,  (GLfloat*)&smoothPointSizeRange);
	maxSmoothPointSize = std::min(aliasedPointSizeRange.y, smoothPointSizeRange.y);

	// some GLSL relevant information
	{
		glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &glslMaxUniformBufferBindings);
		glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,      &glslMaxUniformBufferSize);
		glGetIntegerv(GL_MAX_VARYING_FLOATS,          &glslMaxVaryings);
		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,          &glslMaxAttributes);
		glGetIntegerv(GL_MAX_DRAW_BUFFERS,            &glslMaxDrawBuffers);
		glGetIntegerv(GL_MAX_ELEMENTS_INDICES,        &glslMaxRecommendedIndices);
		glGetIntegerv(GL_MAX_ELEMENTS_VERTICES,       &glslMaxRecommendedVertices);
		glslMaxVaryings /= 4; // GL_MAX_VARYING_FLOATS returns max individual floats, we want float4
	}

	// detect if GL_DEPTH_COMPONENT24 is supported (many ATIs don't do so)
	{
		// ATI seems to support GL_DEPTH_COMPONENT24 for static textures, but you can't render to them
		/*
		GLint state = 0;
		glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 16, 16, 0, GL_LUMINANCE, GL_FLOAT, NULL);
		glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &state);
		support24bitDepthBuffers = (state > 0);
		*/

		support24bitDepthBuffers = false;
		if (FBO::IsSupported() && !atiHacks) {
			const int fboSizeX = 16, fboSizeY = 16;

			FBO fbo;
			fbo.Bind();
			fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, fboSizeX, fboSizeY);
			fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT,  GL_DEPTH_COMPONENT24, fboSizeX, fboSizeY);
			const GLenum status = fbo.GetStatus();
			fbo.Unbind();

			support24bitDepthBuffers = (status == GL_FRAMEBUFFER_COMPLETE_EXT);
		}
	}

	// print info
	LOG(
		"GL info:\n"
		"\thaveARB: %i, haveGLSL: %i, ATI hacks: %i\n"
		"\tFBO support: %i, NPOT-texture support: %i, 24bit Z-buffer support: %i\n"
		"\tmaximum texture size: %i, compress MIP-map textures: %i\n"
		"\tmaximum SmoothPointSize: %0.0f, maximum vec4 varying/attributes: %i/%i\n"
		"\tmaximum drawbuffers: %i, maximum recommended indices/vertices: %i/%i\n"
		"\tnumber of UniformBufferBindings: %i (%ikB)",
		haveARB, haveGLSL, atiHacks,
		FBO::IsSupported(), supportNPOTs, support24bitDepthBuffers,
		maxTextureSize, compressTextures, maxSmoothPointSize,
		glslMaxVaryings, glslMaxAttributes, glslMaxDrawBuffers,
		glslMaxRecommendedIndices, glslMaxRecommendedVertices,
		glslMaxUniformBufferBindings, glslMaxUniformBufferSize / 1024
	);

	teamNanospray = configHandler->GetBool("TeamNanoSpray");
}
Beispiel #10
0
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum)
{
	const std::string fn    = FileSystem::GetFilename(fullName);
	const std::string fpath = FileSystem::GetDirectory(fullName);
	const std::string lcfn  = StringToLower(fn);

	// Cache variables
	std::map<std::string, ArchiveInfo>::iterator aii;
	bool cached = false;

	// Stat file
	struct stat info = {0};
	int statfailed = stat(fullName.c_str(), &info);

	// If stat fails, assume the archive is not broken nor cached
	if (!statfailed) {
		// Determine whether this archive has earlier be found to be broken
		std::map<std::string, BrokenArchive>::iterator bai = brokenArchives.find(lcfn);
		if (bai != brokenArchives.end()) {
			if ((unsigned)info.st_mtime == bai->second.modified && fpath == bai->second.path) {
				bai->second.updated = true;
				return;
			}
		}


		// Determine whether to rely on the cached info or not
		if ((aii = archiveInfos.find(lcfn)) != archiveInfos.end()) {
			// This archive may have been obsoleted, do not process it if so
			if (aii->second.replaced.length() > 0) {
				return;
			}

			if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) {
				cached = true;
				aii->second.updated = true;
			}

			// If we are here, we could have invalid info in the cache
			// Force a reread if it is a directory archive (.sdd), as
			// st_mtime only reflects changes to the directory itself,
			// not the contents.
			if (!cached) {
				archiveInfos.erase(aii);
			}
		}
	}

	// Time to parse the info we are interested in
	if (cached) {
		// If cached is true, aii will point to the archive
		if (doChecksum && (aii->second.checksum == 0))
			aii->second.checksum = GetCRC(fullName);
	} else {
		IArchive* ar = archiveLoader.OpenArchive(fullName);
		if (!ar || !ar->IsOpen()) {
			LOG("Unable to open archive: %s", fullName.c_str());
			return;
		}

		ArchiveInfo ai;

		std::string error;
		std::string mapfile;

		const bool hasModinfo = ar->FileExists("modinfo.lua");
		const bool hasMapinfo = ar->FileExists("mapinfo.lua");

		// check for smf/sm3 and if the uncompression of important files is too costy
		for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) {
			std::string name;
			int size;
			ar->FileInfo(fid, name, size);
			const std::string lowerName = StringToLower(name);
			const std::string ext = FileSystem::GetExtension(lowerName);

			if ((ext == "smf") || (ext == "sm3")) {
				mapfile = name;
			}

			const unsigned char metaFileClass = GetMetaFileClass(lowerName);
			if ((metaFileClass != 0) && !(ar->HasLowReadingCost(fid))) {
				// is a meta-file and not cheap to read
				if (metaFileClass == 1) {
					// 1st class
					error = "Unpacking/reading cost for meta file " + name
							+ " is too high, please repack the archive (make sure to use a non-solid algorithm, if applicable)";
					break;
				} else if (metaFileClass == 2) {
					// 2nd class
					LOG_SL(LOG_SECTION_ARCHIVESCANNER, L_WARNING,
							"Archive %s: The cost for reading a 2nd-class meta-file is too high: %s",
							fullName.c_str(), name.c_str());
				}
			}
		}

		/*
		if (!error.empty()) {
			// we already have an error, no further evaluation required
		}
		*/
		if (hasMapinfo || !mapfile.empty()) {
			// it is a map
			if (hasMapinfo) {
				ScanArchiveLua(ar, "mapinfo.lua", ai, error);
			} else if (hasModinfo) {
				// backwards-compat for modinfo.lua in maps
				ScanArchiveLua(ar, "modinfo.lua", ai, error);
			}

			if (ai.archiveData.GetName().empty()) {
				// FIXME The name will never be empty, if version is set (see HACK in ArchiveData)
				ai.archiveData.SetInfoItemValueString("name_pure", FileSystem::GetBasename(mapfile));
				ai.archiveData.SetInfoItemValueString("name", FileSystem::GetBasename(mapfile));
			}
			if (ai.archiveData.GetMapFile().empty()) {
				ai.archiveData.SetInfoItemValueString("mapfile", mapfile);
			}

			AddDependency(ai.archiveData.GetDependencies(), "Map Helper v1");
			ai.archiveData.SetInfoItemValueInteger("modType", modtype::map);

			LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s",
					ai.archiveData.GetNameVersioned().c_str());
		} else if (hasModinfo) {
			// it is a mod
			ScanArchiveLua(ar, "modinfo.lua", ai, error);
			if (ai.archiveData.GetModType() == modtype::primary) {
				AddDependency(ai.archiveData.GetDependencies(), "Spring content v1");
			}

			LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s",
					ai.archiveData.GetNameVersioned().c_str());
		} else {
			// neither a map nor a mod: error
			error = "missing modinfo.lua/mapinfo.lua";
		}

		delete ar;

		if (!error.empty()) {
			// for some reason, the archive is marked as broken
			LOG_L(L_WARNING, "Failed to scan %s (%s)",
					fullName.c_str(), error.c_str());

			// record it as broken, so we don't need to look inside everytime
			BrokenArchive ba;
			ba.path = fpath;
			ba.modified = info.st_mtime;
			ba.updated = true;
			ba.problem = error;
			brokenArchives[lcfn] = ba;
			return;
		}

		ai.path = fpath;
		ai.modified = info.st_mtime;
		ai.origName = fn;
		ai.updated = true;

		// Optionally calculate a checksum for the file
		// To prevent reading all files in all directory (.sdd) archives
		// every time this function is called, directory archive checksums
		// are calculated on the fly.
		if (doChecksum) {
			ai.checksum = GetCRC(fullName);
		} else {
			ai.checksum = 0;
		}

		archiveInfos[lcfn] = ai;
	}
}
Beispiel #11
0
void CArchiveScanner::ReadCacheData(const std::string& filename)
{
	if (!FileSystem::FileExists(filename)) {
		LOG_L(L_INFO, "Archive cache doesn't exist: %s", filename.c_str());
		return;
	}

	LuaParser p(filename, SPRING_VFS_RAW, SPRING_VFS_BASE);

	if (!p.Execute()) {
		LOG_L(L_ERROR, "Failed to parse archive cache: %s",
				p.GetErrorLog().c_str());
		return;
	}
	const LuaTable archiveCache = p.GetRoot();
	const LuaTable archives = archiveCache.SubTable("archives");

	// Do not load old version caches
	const int ver = archiveCache.GetInt("internalVer", (INTERNAL_VER + 1));
	if (ver != INTERNAL_VER) {
		return;
	}

	for (int i = 1; archives.KeyExists(i); ++i) {
		const LuaTable curArchive = archives.SubTable(i);
		const LuaTable archived = curArchive.SubTable("archivedata");
		ArchiveInfo ai;

		ai.origName = curArchive.GetString("name", "");
		ai.path     = curArchive.GetString("path", "");

		// do not use LuaTable.GetInt() for 32-bit integers, the Spring lua
		// library uses 32-bit floats to represent numbers, which can only
		// represent 2^24 consecutive integers
		ai.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10);
		ai.checksum = strtoul(curArchive.GetString("checksum", "0").c_str(), 0, 10);
		ai.updated = false;

		ai.archiveData = CArchiveScanner::ArchiveData(archived, true);
		if (ai.archiveData.GetModType() == modtype::map) {
			AddDependency(ai.archiveData.GetDependencies(), "Map Helper v1");
		} else if (ai.archiveData.GetModType() == modtype::primary) {
			AddDependency(ai.archiveData.GetDependencies(), "Spring content v1");
		}

		std::string lcname = StringToLower(ai.origName);
		archiveInfos[lcname] = ai;
	}

	const LuaTable brokenArchives = archiveCache.SubTable("brokenArchives");

	for (int i = 1; brokenArchives.KeyExists(i); ++i) {
		const LuaTable curArchive = brokenArchives.SubTable(i);
		BrokenArchive ba;
		std::string name = curArchive.GetString("name", "");

		ba.path = curArchive.GetString("path", "");
		ba.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10);
		ba.updated = false;
		ba.problem = curArchive.GetString("problem", "unknown");

		StringToLowerInPlace(name);
		this->brokenArchives[name] = ba;
	}

	isDirty = false;
}
Beispiel #12
0
void CArchiveScanner::Scan(const std::string& curPath, bool doChecksum)
{
	isDirty = true;

	const int flags = (FileQueryFlags::INCLUDE_DIRS | FileQueryFlags::RECURSE);
	const std::vector<std::string> &found = dataDirsAccess.FindFiles(curPath, "*", flags);

	for (std::vector<std::string>::const_iterator it = found.begin(); it != found.end(); ++it) {
		std::string fullName = *it;

		// Strip
		const char lastFullChar = fullName[fullName.size() - 1];
		if ((lastFullChar == '/') || (lastFullChar == '\\')) {
			fullName = fullName.substr(0, fullName.size() - 1);
		}

		const std::string fpath = FileSystem::GetDirectory(fullName);
		const std::string lcfpath = StringToLower(fpath);

		// Exclude archivefiles found inside directory archives (.sdd)
		if (lcfpath.find(".sdd") != std::string::npos) {
			continue;
		}

		// Exclude archivefiles found inside hidden directories
		if ((lcfpath.find("/hidden/")   != std::string::npos) ||
		    (lcfpath.find("\\hidden\\") != std::string::npos)) {
			continue;
		}

#if       !defined(DEDICATED) && !defined(UNITSYNC)
		Watchdog::ClearTimer(WDT_MAIN);
#endif // !defined(DEDICATED) && !defined(UNITSYNC)
		// Is this an archive we should look into?
		if (archiveLoader.IsArchiveFile(fullName)) {
			ScanArchive(fullName, doChecksum);
		}
	}

	// Now we'll have to parse the replaces-stuff found in the mods
	for (std::map<std::string, ArchiveInfo>::iterator aii = archiveInfos.begin(); aii != archiveInfos.end(); ++aii) {
		for (std::vector<std::string>::const_iterator i = aii->second.archiveData.GetReplaces().begin(); i != aii->second.archiveData.GetReplaces().end(); ++i) {

			const std::string lcname = StringToLower(*i);
			std::map<std::string, ArchiveInfo>::iterator ar = archiveInfos.find(lcname);

			// If it's not there, we will create a new entry
			if (ar == archiveInfos.end()) {
				ArchiveInfo tmp;
				archiveInfos[lcname] = tmp;
				ar = archiveInfos.find(lcname);
			}

			// Overwrite the info for this archive with a replaced pointer
			ar->second.path = "";
			ar->second.origName = lcname;
			ar->second.modified = 1;

			ArchiveData empty;
			ar->second.archiveData = empty;
			ar->second.updated = true;
			ar->second.replaced = aii->first;
		}
	}
}
Beispiel #13
0
std::vector<TexFile*> C3DOTextureHandler::LoadTexFiles()
{
	CFileHandler teamTexFile("unittextures/tatex/teamtex.txt");
	CFileHandler paletteFile("unittextures/tatex/palette.pal");

	CSimpleParser parser(teamTexFile);

	std::set<std::string> teamTexes;
	while (!parser.Eof()) {
		teamTexes.insert(StringToLower(parser.GetCleanLine()));
	}

	std::vector<TexFile*> texfiles;

	const std::vector<std::string>& filesBMP = CFileHandler::FindFiles("unittextures/tatex/", "*.bmp");
	std::vector<std::string> files = CFileHandler::FindFiles("unittextures/tatex/", "*.tga");
	files.insert(files.end(), filesBMP.begin(), filesBMP.end());

	std::set<string> usedNames;
	for (std::vector<std::string>::iterator fi = files.begin(); fi != files.end(); ++fi) {
		const std::string& s = *fi;
		const std::string s2 = StringToLower(FileSystem::GetBasename(s));

		// avoid duplicate names and give tga images priority
		if (usedNames.find(s2) != usedNames.end()) {
			continue;
		}
		usedNames.insert(s2);

		if(teamTexes.find(s2) == teamTexes.end()){
			TexFile* tex = CreateTex(s, s2, false);
			texfiles.push_back(tex);
		} else {
			TexFile* tex = CreateTex(s, s2, true);
			texfiles.push_back(tex);
		}
	}

	if (paletteFile.FileExists()) {
		palette.Init(paletteFile);
	}

	for (unsigned a = 0; a < CTAPalette::NUM_PALETTE_ENTRIES; ++a) {
		TexFile* tex = new TexFile();
		tex->name = "ta_color" + IntToString(a, "%i");
		tex->tex.Alloc(1, 1);
		tex->tex.mem[0] = palette[a][0];
		tex->tex.mem[1] = palette[a][1];
		tex->tex.mem[2] = palette[a][2];
		tex->tex.mem[3] = 0; // teamcolor

		tex->tex2.Alloc(1, 1);
		tex->tex2.mem[0] = 0;  // self illum
		tex->tex2.mem[1] = 30; // reflectivity
		tex->tex2.mem[2] =  0;
		tex->tex2.mem[3] = 255;

		texfiles.push_back(tex);
	}

	return texfiles;
}
Beispiel #14
0
bool CKeyBindings::ExecuteCommand(const string& line)
{
	const vector<string> words = CSimpleParser::Tokenize(line, 2);

	if (words.empty()) {
		return false;
	}
	const string command = StringToLower(words[0]);

	if (command == "keydebug") {
		const int curLogLevel = log_filter_section_getMinLevel(LOG_SECTION_KEY_BINDINGS);
		bool debug = (curLogLevel == LOG_LEVEL_DEBUG);
		if (words.size() == 1) {
			// toggle
			debug = !debug;
		} else if (words.size() >= 2) {
			// set
			debug = atoi(words[1].c_str());
		}
		if (debug && !LOG_IS_ENABLED_STATIC(L_DEBUG)) {
			LOG_L(L_WARNING,
					"You have to run a DEBUG build to be able to log L_DEBUG messages");
		}
		log_filter_section_setMinLevel(LOG_SECTION_KEY_BINDINGS,
				(debug ? LOG_LEVEL_DEBUG : LOG_LEVEL_INFO));
	}
	else if ((command == "fakemeta") && (words.size() > 1)) {
		if (!SetFakeMetaKey(words[1])) { return false; }
	}
	else if ((command == "keyset") && (words.size() > 2)) {
		if (!AddNamedKeySet(words[1], words[2])) { return false; }
	}
	else if ((command == "keysym") && (words.size() > 2)) {
		if (!AddKeySymbol(words[1], words[2])) { return false; }
	}
	else if ((command == "bind") && (words.size() > 2)) {
		if (!Bind(words[1], words[2])) { return false; }
	}
	else if ((command == "unbind") && (words.size() > 2)) {
		if (!UnBind(words[1], words[2])) { return false; }
	}
	else if ((command == "unbindaction") && (words.size() > 1)) {
		if (!UnBindAction(words[1])) { return false; }
	}
	else if ((command == "unbindkeyset") && (words.size() > 1)) {
		if (!UnBindKeyset(words[1])) { return false; }
	}
	else if (command == "unbindall") {
		bindings.clear();
		keyCodes->Reset();
		namedKeySets.clear();
		typeBindings.clear();
		Bind("enter", "chat"); // bare minimum
	}
	else {
		return false;
	}

	if (userCommand) {
		Sanitize();
	}

	return false;
}
Beispiel #15
0
bool CTextureAtlas::TextureExists(const std::string& name)
{
	return textures.find(StringToLower(name)) != textures.end();
}
Beispiel #16
0
CFactoryCAI::CFactoryCAI(CUnit* owner)
: CCommandAI(owner),
	building(false),
	lastRestrictedWarning(0)
{
	commandQue.SetQueueType(CCommandQueue::BuildQueueType);
	newUnitCommands.SetQueueType(CCommandQueue::NewUnitQueueType);

	CommandDescription c;

	// can't check for canmove here because it should be possible to assign rallypoint
	// with a non-moving factory.
	c.id=CMD_MOVE;
	c.action="move";
	c.type=CMDTYPE_ICON_MAP;
	c.name="Move";
	c.mouseicon=c.name;
	c.tooltip="Move: Order ready built units to move to a position";
	possibleCommands.push_back(c);

	if (owner->unitDef->canPatrol) {
		c.id=CMD_PATROL;
		c.action="patrol";
		c.type=CMDTYPE_ICON_MAP;
		c.name="Patrol";
		c.mouseicon=c.name;
		c.tooltip="Patrol: Order ready built units to patrol to one or more waypoints";
		possibleCommands.push_back(c);
	}

	if (owner->unitDef->canFight) {
		c.id = CMD_FIGHT;
		c.action="fight";
		c.type = CMDTYPE_ICON_MAP;
		c.name = "Fight";
		c.mouseicon=c.name;
		c.tooltip = "Fight: Order ready built units to take action while moving to a position";
		possibleCommands.push_back(c);
	}

	if (owner->unitDef->canGuard) {
		c.id=CMD_GUARD;
		c.action="guard";
		c.type=CMDTYPE_ICON_UNIT;
		c.name="Guard";
		c.mouseicon=c.name;
		c.tooltip="Guard: Order ready built units to guard another unit and attack units attacking it";
		possibleCommands.push_back(c);
	}

	CFactory* fac=(CFactory*)owner;

	map<int,string>::const_iterator bi;
	for (bi = fac->unitDef->buildOptions.begin(); bi != fac->unitDef->buildOptions.end(); ++bi) {
		const string name = bi->second;

		const UnitDef* ud = unitDefHandler->GetUnitByName(name);
		if (ud == NULL) {
		  string errmsg = "MOD ERROR: loading ";
		  errmsg += name.c_str();
		  errmsg += " for ";
		  errmsg += owner->unitDef->name;
			throw content_error(errmsg);
		}

		CommandDescription c;
		c.id = -ud->id; //build options are always negative
		c.action = "buildunit_" + StringToLower(ud->name);
		c.type = CMDTYPE_ICON;
		c.name = name;
		c.mouseicon = c.name;
		c.disabled = (ud->maxThisUnit <= 0);

		char tmp[1024];
		sprintf(tmp, "\nHealth %.0f\nMetal cost %.0f\nEnergy cost %.0f Build time %.0f",
		        ud->health, ud->metalCost, ud->energyCost, ud->buildTime);
		if (c.disabled) {
			c.tooltip = "\xff\xff\x22\x22" "DISABLED: " "\xff\xff\xff\xff";
		} else {
			c.tooltip = "Build: ";
		}
		c.tooltip += ud->humanName + " - " + ud->tooltip + tmp;

		possibleCommands.push_back(c);
		BuildOption bo;
		bo.name = name;
		bo.fullName = name;
		bo.numQued = 0;
		buildOptions[c.id] = bo;
	}
}
Beispiel #17
0
AtlasedTexture* CTextureAtlas::GetTexturePtr(const std::string& name)
{
	return &textures[StringToLower(name)];
}
Beispiel #18
0
static std::map<std::string, int> GetEnabledSections() {
    std::map<std::string, int> sectionLevelMap;

    std::string enabledSections = ",";
    std::string envSections = ",";

#if defined(UNITSYNC)
#if defined(DEBUG)
    // unitsync logging in debug mode always on
    // configHandler cannot be accessed here in unitsync, as it may not exist.
    enabledSections += "unitsync,ArchiveScanner,";
#endif
#else
#if defined(DEDICATED)
    enabledSections += "DedicatedServer,";
#endif
#if !defined(DEBUG)
    // Always show at least INFO level of these sections
    enabledSections += "Sound,";
#endif
    enabledSections += StringToLower(configHandler->GetString("LogSections"));
#endif

    if (getenv("SPRING_LOG_SECTIONS") != NULL) {
        // allow disabling all sections from the env var by setting it to "none"
        envSections += getenv("SPRING_LOG_SECTIONS");
        envSections = StringToLower(envSections);

        if (envSections == "none") {
            enabledSections = "";
        } else {
            enabledSections += envSections;
        }
    }

    enabledSections = StringToLower(enabledSections);
    enabledSections = StringStrip(enabledSections, " \t\n\r");

    // make the last "section:level" substring findable
    if (!enabledSections.empty() && enabledSections.back() != ',')
        enabledSections += ",";

    // n=1 because <enabledSections> always starts with a ',' (if non-empty)
    for (size_t n = 1; n < enabledSections.size(); ) {
        const size_t k = enabledSections.find(",", n);

        if (k != std::string::npos) {
            const std::string& sub = enabledSections.substr(n, k - n);

            if (!sub.empty()) {
                const size_t sepChr = sub.find(":");

                const std::string& logSec = (sepChr != std::string::npos)? sub.substr(         0,            sepChr): sub;
                const std::string& logLvl = (sepChr != std::string::npos)? sub.substr(sepChr + 1, std::string::npos):  "";

                if (!logLvl.empty()) {
                    sectionLevelMap[logSec] = StringToInt(logLvl);
                } else {
#if defined(DEBUG)
                    sectionLevelMap[logSec] = LOG_LEVEL_DEBUG;
#else
                    sectionLevelMap[logSec] = DEFAULT_LOG_LEVEL;
#endif

                }
            }

            n = k + 1;
        } else {
            n = k;
        }
    }

    return sectionLevelMap;
}
Beispiel #19
0
/*
 * CArchiveScanner::ArchiveData
 */
CArchiveScanner::ArchiveData::ArchiveData(const LuaTable& archiveTable, bool fromCache)
{
	if (!archiveTable.IsValid())
		return;

	std::vector<std::string> keys;
	if (!archiveTable.GetKeys(keys))
		return;

	for (std::string& key: keys) {
		const std::string& keyLower = StringToLower(key);

		if (ArchiveData::IsReservedKey(keyLower))
			continue;

		if (keyLower == "modtype") {
			SetInfoItemValueInteger(key, archiveTable.GetInt(key, 0));
			continue;
		}

		switch (archiveTable.GetType(key)) {
			case LuaTable::STRING: {
				SetInfoItemValueString(key, archiveTable.GetString(key, ""));
			} break;
			case LuaTable::NUMBER: {
				SetInfoItemValueFloat(key, archiveTable.GetFloat(key, 0.0f));
			} break;
			case LuaTable::BOOLEAN: {
				SetInfoItemValueBool(key, archiveTable.GetBool(key, false));
			} break;
			default: {
				// just ignore unsupported types (most likely to be lua-tables)
				//throw content_error("Lua-type " + IntToString(luaType) + " not supported in archive-info, but it is used on key \"" + *key + "\"");
			} break;
		}
	}

	const LuaTable& _dependencies = archiveTable.SubTable("depend");
	const LuaTable& _replaces = archiveTable.SubTable("replace");

	for (int dep = 1; _dependencies.KeyExists(dep); ++dep) {
		dependencies.push_back(_dependencies.GetString(dep, ""));
	}
	for (int rep = 1; _replaces.KeyExists(rep); ++rep) {
		replaces.push_back(_replaces.GetString(rep, ""));
	}

	// FIXME
	// XXX HACK needed until lobbies, lobbyserver and unitsync are sorted out
	// so they can uniquely identify different versions of the same mod.
	// (at time of this writing they use name only)

	// NOTE when changing this, this function is used both by the code that
	// reads ArchiveCache.lua and the code that reads modinfo.lua from the mod.
	// so make sure it doesn't keep adding stuff to the name everytime
	// Spring/unitsync is loaded.

	const std::string& name = GetNameVersioned();
	const std::string& version = GetVersion();
	if (!version.empty()) {
		if (name.find(version) == std::string::npos) {
			SetInfoItemValueString("name", name + " " + version);
		} else if (!fromCache) {
			LOG_L(L_WARNING, "[%s] version \"%s\" included in name \"%s\"", __func__, version.c_str(), name.c_str());
		}
	}

	if (GetName().empty())
		SetInfoItemValueString("name_pure", name);
}
Beispiel #20
0
void CMiniMap::ConfigCommand(const std::string& line)
{
	const vector<string> words = CSimpleParser::Tokenize(line, 1);
	if (words.empty()) {
		return;
	}
	const string command = StringToLower(words[0]);

	if (command == "fullproxy") {
		if (words.size() >= 2) {
			fullProxy = !!atoi(words[1].c_str());
		} else {
			fullProxy = !fullProxy;
		}
	}
	else if (command == "icons") {
		if (words.size() >= 2) {
			useIcons = !!atoi(words[1].c_str());
		} else {
			useIcons = !useIcons;
		}
	}
	else if (command == "unitexp") {
		if (words.size() >= 2) {
			unitExponent = atof(words[1].c_str());
		}
		UpdateGeometry();
	}
	else if (command == "unitsize") {
		if (words.size() >= 2) {
			unitBaseSize = atof(words[1].c_str());
		}
		unitBaseSize = std::max(0.0f, unitBaseSize);
		UpdateGeometry();
	}
	else if (command == "drawcommands") {
		if (words.size() >= 2) {
			drawCommands = std::max(0, atoi(words[1].c_str()));
		} else {
			drawCommands = (drawCommands > 0) ? 0 : 1;
		}
	}
	else if (command == "drawprojectiles") {
		if (words.size() >= 2) {
			drawProjectiles = !!atoi(words[1].c_str());
		} else {
			drawProjectiles = !drawProjectiles;
		}
	}
	else if (command == "simplecolors") {
		if (words.size() >= 2) {
			simpleColors = !!atoi(words[1].c_str());
		} else {
			simpleColors = !simpleColors;
		}
	}

	// the following commands can not be used in dualscreen mode
	if (gu->dualScreenMode) {
		return;
	}

	if ((command == "geo") || (command == "geometry")) {
		if (words.size() < 2) {
			return;
		}
		ParseGeometry(words[1]);
		UpdateGeometry();
	}
	else if ((command == "min") || (command == "minimize")) {
		if (words.size() >= 2) {
			minimized = !!atoi(words[1].c_str());
		} else {
			minimized = !minimized;
		}
	}
	else if ((command == "max") ||
	         (command == "maximize") || (command == "maxspect")) {
		bool newMax = maximized;
		if (words.size() >= 2) {
			newMax = !!atoi(words[1].c_str());
		} else {
			newMax = !newMax;
		}
		if (newMax != maximized) {
			ToggleMaximized(command == "maxspect");
		}
	}
}
Beispiel #21
0
bool CArchiveScanner::CheckCachedData(const std::string& fullName, unsigned* modified, bool doChecksum)
{
	// If stat fails, assume the archive is not broken nor cached
	if ((*modified = FileSystemAbstraction::GetFileModificationTime(fullName)) == 0)
		return false;

	const std::string& fn    = FileSystem::GetFilename(fullName);
	const std::string& fpath = FileSystem::GetDirectory(fullName);
	const std::string& lcfn  = StringToLower(fn);


	// Determine whether this archive has earlier be found to be broken
	auto bai = brokenArchives.find(lcfn);

	if (bai != brokenArchives.end()) {
		BrokenArchive& ba = bai->second;

		if (*modified == ba.modified && fpath == ba.path) {
			return (ba.updated = true);
		}
	}


	// Determine whether to rely on the cached info or not
	auto aii = archiveInfos.find(lcfn);

	if (aii != archiveInfos.end()) {
		ArchiveInfo& ai = aii->second;

		// This archive may have been obsoleted, do not process it if so
		if (!ai.replaced.empty())
			return true;

		if (*modified == ai.modified && fpath == ai.path) {
			// cache found update checksum if wanted
			ai.updated = true;

			if (doChecksum && (ai.checksum == 0))
				ai.checksum = GetCRC(fullName);

			return true;
		}

		if (ai.updated) {
			LOG_L(L_ERROR, "[AS::%s] found a \"%s\" already in \"%s\", ignoring.", __func__, fullName.c_str(), (ai.path + ai.origName).c_str());

			if (baseContentArchives.find(aii->first) == baseContentArchives.end())
				return true; // ignore

			throw user_error(
				std::string("duplicate base content detected:\n\t") + ai.path +
				std::string("\n\t") + fpath +
				std::string("\nPlease fix your configuration/installation as this can cause desyncs!"));
		}

		// If we are here, we could have invalid info in the cache
		// Force a reread if it is a directory archive (.sdd), as
		// st_mtime only reflects changes to the directory itself,
		// not the contents.
		archiveInfos.erase(aii);
	}

	return false;
}
Beispiel #22
0
static bool parseOption(const LuaTable& root, int index, Option& opt,
		std::set<string>& optionsSet, CLogSubsystem& logSubsystem) {

	const LuaTable& optTbl = root.SubTable(index);
	if (!optTbl.IsValid()) {
		logOutput.Print(logSubsystem,
				"parseOption: subtable %d invalid", index);
		return false;
	}

	// common options properties
	opt.key = optTbl.GetString("key", "");
	if (opt.key.empty()
			|| (opt.key.find_first_of(Option_badKeyChars) != string::npos)) {
		logOutput.Print(logSubsystem,
				"parseOption: empty key or key contains bad characters");
		return false;
	}
	opt.key = StringToLower(opt.key);

	opt.scope = optTbl.GetString("scope", "scope");
	if (opt.key.empty()
		   || (opt.key.find_first_of(Option_badKeyChars) != string::npos)) {
		logOutput.Print(logSubsystem,
						"parseOption: empty key or key contains bad characters");
		return false;
	}
	opt.scope = StringToLower(opt.scope);

	if (optionsSet.find(opt.key) != optionsSet.end()) {
		logOutput.Print(logSubsystem, "parseOption: key %s exists already",
				opt.key.c_str());
		return false;
	}
	opt.name = optTbl.GetString("name", opt.key);
	if (opt.name.empty()) {
		logOutput.Print(logSubsystem, "parseOption: %s: empty name",
				opt.key.c_str());
		return false;
	}
	opt.desc = optTbl.GetString("desc", opt.name);

	opt.section = optTbl.GetString("section", "");
	opt.style = optTbl.GetString("style", "");

	opt.type = optTbl.GetString("type", "");
	opt.type = StringToLower(opt.type);

	// option type specific properties
	if (opt.type == "bool") {
		opt.typeCode = opt_bool;
		opt.boolDef = optTbl.GetBool("def", false);
	}
	else if (opt.type == "number") {
		opt.typeCode = opt_number;
		opt.numberDef  = optTbl.GetFloat("def",  0.0f);
		opt.numberMin  = optTbl.GetFloat("min",  -1.0e30f);
		opt.numberMax  = optTbl.GetFloat("max",  +1.0e30f);
		opt.numberStep = optTbl.GetFloat("step", 0.0f);
	}
	else if (opt.type == "string") {
		opt.typeCode = opt_string;
		opt.stringDef    = optTbl.GetString("def", "");
		opt.stringMaxLen = optTbl.GetInt("maxlen", 0);
	}
	else if (opt.type == "list") {
		opt.typeCode = opt_list;

		const LuaTable& listTbl = optTbl.SubTable("items");
		if (!listTbl.IsValid()) {
			logOutput.Print(logSubsystem, "parseOption: %s: subtable items invalid", opt.key.c_str());
			return false;
		}

		for (int i = 1; listTbl.KeyExists(i); i++) {
			OptionListItem item;

			// string format
			item.key = listTbl.GetString(i, "");
			if (!item.key.empty() &&
			    (item.key.find_first_of(Option_badKeyChars) == string::npos)) {
				item.name = item.key;
				item.desc = item.name;
				opt.list.push_back(item);
				continue;
			}

			// table format  (name & desc)
			const LuaTable& itemTbl = listTbl.SubTable(i);
			if (!itemTbl.IsValid()) {
				logOutput.Print(logSubsystem,
						"parseOption: %s: subtable %d of subtable items invalid",
						opt.key.c_str(), i);
				break;
			}
			item.key = itemTbl.GetString("key", "");
			if (item.key.empty() || (item.key.find_first_of(Option_badKeyChars) != string::npos)) {
				logOutput.Print(logSubsystem,
						"parseOption: %s: empty key or key contains bad characters",
						opt.key.c_str());
				return false;
			}
			item.key = StringToLower(item.key);
			item.name = itemTbl.GetString("name", item.key);
			if (item.name.empty()) {
				logOutput.Print(logSubsystem, "parseOption: %s: empty name",
						opt.key.c_str());
				return false;
			}
			item.desc = itemTbl.GetString("desc", item.name);
			opt.list.push_back(item);
		}

		if (opt.list.size() <= 0) {
			logOutput.Print(logSubsystem, "parseOption: %s: empty list",
					opt.key.c_str());
			return false; // no empty lists
		}

		opt.listDef = optTbl.GetString("def", opt.list[0].name);
	}
	else if (opt.type == "section") {
		opt.typeCode = opt_section;
	}
	else {
		logOutput.Print(logSubsystem, "parseOption: %s: unknown type %s",
				opt.key.c_str(), opt.type.c_str());
		return false; // unknown type
	}

	optionsSet.insert(opt.key);

	return true;
}
void CArchiveScanner::Scan(const string& curPath, bool checksum)
{
	isDirty = true;

	std::vector<std::string> found = filesystem.FindFiles(curPath, "*", FileSystem::RECURSE | FileSystem::INCLUDE_DIRS);
	struct stat info;
	for (std::vector<std::string>::iterator it = found.begin(); it != found.end(); ++it) {
		stat(it->c_str(),&info);

		string fullName = *it;
		string fn = filesystem.GetFilename(fullName);
		string fpath = filesystem.GetDirectory(fullName);
		string lcfn = StringToLower(fn);
		string lcfpath = StringToLower(fpath);

		// Exclude archivefiles found inside directory (.sdd) archives.
		string::size_type sdd = lcfpath.find(".sdd");
		if (sdd != string::npos)
			continue;

		// Is this an archive we should look into?
		if (CArchiveFactory::IsArchive(fullName)) {

			// Determine whether to rely on the cached info or not
			bool cached = false;

			map<string, ArchiveInfo>::iterator aii = archiveInfo.find(lcfn);
			if (aii != archiveInfo.end()) {

				// This archive may have been obsoleted, do not process it if so
				if (aii->second.replaced.length() > 0)
					continue;

				if (S_ISDIR(info.st_mode)) {
					struct stat info2;
					std::vector<std::string> sddfiles = filesystem.FindFiles(fpath, "*", FileSystem::RECURSE | FileSystem::INCLUDE_DIRS);
					for (std::vector<std::string>::iterator sddit = found.begin(); sddit != found.end(); ++sddit) {
						stat(sddit->c_str(), &info2);
						if (info.st_mtime < info2.st_mtime) {
							info.st_mtime = info2.st_mtime;
						}
					}
				}

				if (info.st_mtime == aii->second.modified && fpath == aii->second.path) {
					cached = true;
					aii->second.updated = true;
				}

				// If we are here, we could have invalid info in the cache
				// Force a reread if it's a directory archive, as st_mtime only
				// reflects changes to the directory itself, not the contents.
				if (!cached) {
					archiveInfo.erase(aii);
				}
			}

			// Time to parse the info we are interested in
			if (!cached) {
				CArchiveBase* ar = CArchiveFactory::OpenArchive(fullName);
				if (ar) {
					int cur;
					string name;
					int size;
					ArchiveInfo ai;

					cur = ar->FindFiles(0, &name, &size);
					while (cur != 0) {
						//printf("found %s %d\n", name.c_str(), size);

						string ext = StringToLower(name.substr(name.find_last_of('.') + 1));

						// only accept new format maps
						if (ext == "smf" || ext == "sm3") {
							MapData md;
							if (name.find_last_of('\\') == string::npos && name.find_last_of('/') == string::npos) {
								md.name = name;
								md.virtualPath = "/";
							}
							else {
								if (name.find_last_of('\\') == string::npos) {
									md.name = name.substr(name.find_last_of('/') + 1);
									md.virtualPath = name.substr(0, name.find_last_of('/') + 1);	// include the backslash
								} else {
									md.name = name.substr(name.find_last_of('\\') + 1);
									md.virtualPath = name.substr(0, name.find_last_of('\\') + 1);	// include the backslash
								}
								//md.name = md.name.substr(0, md.name.find_last_of('.'));
							}
							ai.mapData.push_back(md);
						}

						if (name == "modinfo.tdf") {
							int fh = ar->OpenFile(name);
							if (fh) {
								int fsize = ar->FileSize(fh);

								void* buf = malloc(fsize);
								ar->ReadFile(fh, buf, fsize);
								ar->CloseFile(fh);
								try {
									TdfParser p( reinterpret_cast<char*>(buf), fsize );
									ai.modData = GetModData(&p, "mod");
								} catch (const TdfParser::parse_error& e) {
									// Silently ignore mods with parse errors
								}
								free(buf);
							}

						}

						cur = ar->FindFiles(cur, &name, &size);
					}

					ai.path = fpath;
					ai.modified = info.st_mtime;
					ai.origName = fn;
					ai.updated = true;

					delete ar;

					// Optionally calculate a checksum for the file
					// To prevent reading all files in all directory (.sdd) archives every time this function
					// is called, directory archive checksums are calculated on the fly.
					if (checksum) {
						ai.checksum = GetCRC(fullName);
					}
					else {
						ai.checksum = 0;
					}

					archiveInfo[lcfn] = ai;
				}
			}
			else {
				// If cached is true, aii will point to the archive
				if ((checksum) && (aii->second.checksum == 0)) {
					aii->second.checksum = GetCRC(fullName);
				}
			}
		}
	}

	// Now we'll have to parse the replaces-stuff found in the mods
	for (map<string, ArchiveInfo>::iterator aii = archiveInfo.begin(); aii != archiveInfo.end(); ++aii) {
		for (vector<string>::iterator i = aii->second.modData.replaces.begin(); i != aii->second.modData.replaces.end(); ++i) {

			string lcname = StringToLower(*i);

			map<string, ArchiveInfo>::iterator ar = archiveInfo.find(lcname);

			// If it's not there, we will create a new entry
			if (ar == archiveInfo.end()) {
				ArchiveInfo tmp;
				archiveInfo[lcname] = tmp;
				ar = archiveInfo.find(lcname);
			}

			// Overwrite the info for this archive with a replaced pointer
			ar->second.path = "";
			ar->second.origName = lcname;
			ar->second.modified = 1;
			ar->second.mapData.clear();
			ar->second.modData.name = "";
			ar->second.modData.replaces.clear();
			ar->second.updated = true;
			ar->second.replaced = aii->first;
		}
	}
}
Beispiel #24
0
void OovString::setLowerCase(OovStringRef const str)
    {
    *this = str;
    StringToLower(*this);
    }
unsigned int CArchive7Zip::GetCrc32 (const std::string& fileName)
{
	std::string lower = StringToLower(fileName);
	FileData fd = fileData[lower];
	return fd.crc;
}
Beispiel #26
0
int main()
{
	//mysql variables
	MYSQL mysql;
  MYSQL_RES *result;
  MYSQL_ROW row;
  string query;
	
	//initiate mysql
	if (!mysql_init(&mysql))
  {
    cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
    return -1;
  }
  cout << "MySQL initialized." << endl;
  
  //connect to database
  if(!mysql_real_connect(&mysql, "assassins.myprotosite.com", "assassins", "password", "assassins", 0, NULL, 0))
  {
    cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
  	return -1;
  }
  cout << "Connected to database." << endl;
  
	while(true)
	{
		pop p(false);
		p.Connect(MAILHOST);
		p.Login(MAILUSER,MAILPASS);
		if(p.NumUnread() > 0)
		{
			p.Retrieve();
			string from = p.GetFrom();
			cout << "Message from: " << from << endl;
			string message_text = p.GetMessageText();
			message_text = StringToLower(message_text);
			cout << "Message text: '" << message_text << "'" << endl;
			
			
			if(message_text.compare("verify") == 0)
			{
				//they are verifying their number
				//look up phone number in SQL table
				string phone_number = from.substr(0, 10);
				
				cout << "Phone number " << phone_number << " wants to verify. Finding user and updating." << endl;
				
				query = "UPDATE users SET mobile='" + from + "' WHERE mobile='" + phone_number + "';";
		    if(mysql_query(&mysql, query.c_str()))
		    {
	    		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
		      return -1;
		    }
			}
			
			if(message_text.compare("status") == 0)
			{
				//they want to know their current status
				string userid;
				
				query = "SELECT * FROM users WHERE mobile='" + from + "';";
		    if(mysql_query(&mysql, query.c_str()))
		    {
	    		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
		      return -1;
		    }
		    
		    result = mysql_store_result(&mysql);
				if(row = mysql_fetch_row(result))
				{
					userid = row[USERID];
				}
				mysql_free_result(result);
				
				notifyNewContract(userid, true);
			}
			
			if(message_text.length() >= 6)
			{
				if(message_text.substr(0, 6).compare("report") == 0)
				{
					if(message_text.length() >= 13)
					{
						//they want to report a kill
						
				    string userid;
				    string targetid;
				    string targetsecret;
				    string newtarget;
				    string gameid;
						string secret = message_text.substr(7, 6);
						cout << "'" << secret << "'" << endl;
						
						query = "SELECT * FROM users WHERE mobile='" + from + "';";
				    if(mysql_query(&mysql, query.c_str()))
				    {
			    		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
				      return -1;
				    }
				    
				    result = mysql_store_result(&mysql);
						if(row = mysql_fetch_row(result))
						{
							userid = row[USERID];
							targetid = row[TARGETID];
							gameid = row[GAMEID];
						}
						mysql_free_result(result);
						
						query = "SELECT * FROM users WHERE userid='" + targetid + "';";
				    if(mysql_query(&mysql, query.c_str()))
				    {
			    		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
				    	return -1;
				    }
				    
				    result = mysql_store_result(&mysql);
						if(row = mysql_fetch_row(result))
						{
							targetsecret = StringToLower(row[SECRET]);
							newtarget = row[TARGETID];
						}
						mysql_free_result(result);
						
						if(targetsecret.compare(secret) == 0)
						{
							//secret is correct, kill confirmed
							
							query = "UPDATE users SET targetid='-1' WHERE userid='" + targetid + "';";
							if(mysql_query(&mysql, query.c_str()))
							{
						  	cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
							 	return -1;
							}
							
							query = "SELECT * FROM users WHERE targetid='-2';";
						  if(mysql_query(&mysql, query.c_str()))
						  {
					   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
						    return -1;
						  }
						  
						  result = mysql_store_result(&mysql);
							if(row = mysql_fetch_row(result))
							{
								//people are waiting for assignments
								string awaitingid = row[USERID];
								
								query = "UPDATE users SET targetid='" + newtarget + "' WHERE userid='" + awaitingid + "';";
							  if(mysql_query(&mysql, query.c_str()))
							  {
						   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
							    return -1;
							  }
							  notifyNewContract(awaitingid);
								
								query = "UPDATE users SET targetid='" + awaitingid + "' WHERE userid='" + userid + "';";
							  if(mysql_query(&mysql, query.c_str()))
							  {
						   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
							    return -1;
							  }
							}
							else
							{
								//no one's waiting for assignment
								
								if(newtarget.compare(userid) != 0)
								{
									query = "UPDATE users SET targetid='" + newtarget + "' WHERE userid='" + userid + "';";
								  if(mysql_query(&mysql, query.c_str()))
								  {
							   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
								    return -1;
								  }
								}
								else
								{
									//if the target's contract was you, you cannot kill yourself and progress through the game
									//	therefore we must wait for the next kill. when this kill occurs, you will switch contracts
									//	with the person that made the following kill. also, this bracket of code will only run if
									//	there is already no one waiting for assignement, so we dont need to check for that. set target
									//	to -2 to imply awaiting assignment
									
									query = "UPDATE users SET targetid='-2' WHERE userid='" + userid + "';";
								  if(mysql_query(&mysql, query.c_str()))
								  {
							   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
								    return -1;
								  }
								}
							}
							
							//text back telling kill was reported
						  //mail(from, "Kill Reported."); //redundant. if the user is texting the daemon, phone is enabled, therefore
						  //															//		phone will will receive new contract notice.
							
							//check to see if you're last man standing
							query = "SELECT * FROM users WHERE targetid<>-1 AND gameid='" + gameid + "';";
						  if(mysql_query(&mysql, query.c_str()))
						  {
					   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
						    return -1;
						  }
						  result = mysql_store_result(&mysql);
							if(mysql_num_rows(result) == 1)
							{
								//you won
								query = "UPDATE users SET targetid='-3' WHERE userid='" + userid + "'";
							  if(mysql_query(&mysql, query.c_str()))
							  {
						   		cout << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << endl;
							    return -1;
							  }
							}
							
							notifyNewContract(userid);
							notifyNewContract(targetid);
						}
						else
						{
							//secret not correct
						  mail(from, "Secret was incorrrect.");
						}
					}
				}
			}
			
			p.Delete();
		}
		p.Close();
		sleep(5);
	}
	
	return 0;
}
C3DOTextureHandler::C3DOTextureHandler()
{
	CFileHandler teamTexFile("unittextures/tatex/teamtex.txt");
	CFileHandler paletteFile("unittextures/tatex/palette.pal");

	CSimpleParser parser(teamTexFile);

	std::set<std::string> teamTexes;
	while (!teamTexFile.Eof()) {
		teamTexes.insert(StringToLower(parser.GetCleanLine()));
	}

	TexFile* texfiles[10000];

	int numfiles = 0;
	int totalSize = 0;

	const std::vector<std::string>& filesBMP = CFileHandler::FindFiles("unittextures/tatex/", "*.bmp");
	std::vector<std::string> files    = CFileHandler::FindFiles("unittextures/tatex/", "*.tga");
	files.insert(files.end(), filesBMP.begin(), filesBMP.end());

	std::set<string> usedNames;
	for (std::vector<std::string>::iterator fi = files.begin(); fi != files.end(); ++fi) {
		std::string s = std::string(*fi);
		std::string s2 = s;

		s2.erase(0, s2.find_last_of('/') + 1);
		s2 = StringToLower(s2.substr(0, s2.find_last_of('.')));

		// avoid duplicate names and give tga images priority
		if (usedNames.find(s2) != usedNames.end()) {
			continue;
		}
		usedNames.insert(s2);

		if(teamTexes.find(s2) == teamTexes.end()){
			TexFile* tex = CreateTex(s, s2, false);
			texfiles[numfiles++] = tex;
			totalSize += tex->tex.xsize * tex->tex.ysize;
		} else {
			TexFile* tex = CreateTex(s, s2, true);
			texfiles[numfiles++] = tex;
			totalSize += tex->tex.xsize * tex->tex.ysize;
		}
	}

	if (paletteFile.FileExists()) {
		palette.Init(paletteFile);
	}

	for (unsigned a = 0; a < CTAPalette::NUM_PALETTE_ENTRIES; ++a) {
		const std::string name = "ta_color" + IntToString(a, "%i");

		TexFile* tex = new TexFile;
		tex->name = name;
		tex->tex.Alloc(1, 1);
		tex->tex.mem[0] = palette[a][0];
		tex->tex.mem[1] = palette[a][1];
		tex->tex.mem[2] = palette[a][2];
		tex->tex.mem[3] = 0; // teamcolor

		tex->tex2.Alloc(1, 1);
		tex->tex2.mem[0] = 0;  // self illum
		tex->tex2.mem[1] = 30; // reflectivity
		tex->tex2.mem[2] =  0;
		tex->tex2.mem[3] = 255;

		texfiles[numfiles++] = tex;
		totalSize += tex->tex.xsize * tex->tex.ysize;
	}

	// pessimistic guess about how much space will be wasted
	totalSize = (int)(totalSize * 1.2f);

	if (totalSize < 1024*1024) {
		bigTexX = 1024;
		bigTexY = 1024;
	} else if (totalSize < 1024*2048) {
		bigTexX = 1024;
		bigTexY = 2048;
	} else if (totalSize < 2048*2048) {
		bigTexX = 2048;
		bigTexY = 2048;
	} else {
		bigTexX = 2048;
		bigTexY = 2048;
		throw content_error("Too many/large texture in 3do texture-atlas to fit in 2048*2048");
	}

	qsort(texfiles,numfiles,sizeof(TexFile*), CompareTatex2);

	unsigned char* bigtex1 = new unsigned char[bigTexX * bigTexY * 4];
	unsigned char* bigtex2 = new unsigned char[bigTexX * bigTexY * 4];
	for (int a = 0; a < (bigTexX * bigTexY); ++a) {
		bigtex1[a*4 + 0] = 128;
		bigtex1[a*4 + 1] = 128;
		bigtex1[a*4 + 2] = 128;
		bigtex1[a*4 + 3] = 0;

		bigtex2[a*4 + 0] = 0;
		bigtex2[a*4 + 1] = 128;
		bigtex2[a*4 + 2] = 0;
		bigtex2[a*4 + 3] = 255;
	}

	int cury = 0;
	int maxy = 0;
	int curx = 0;
	int foundx = 0;
	int foundy = 0;
	std::list<int2> nextSub;
	std::list<int2> thisSub;
	for (int a = 0; a < numfiles; ++a) {
		CBitmap* curtex1 = &texfiles[a]->tex;
		CBitmap* curtex2 = &texfiles[a]->tex2;

		bool done = false;
		while (!done) {
			// Find space for us
			if (thisSub.empty()) {
				if (nextSub.empty()) {
					cury = maxy;
					maxy += curtex1->ysize;
					if (maxy > bigTexY) {
						throw content_error("Too many/large texture in 3do texture-atlas to fit in 2048*2048");
						break;
					}
					thisSub.push_back(int2(0, cury));
				} else {
					thisSub = nextSub;
					nextSub.clear();
				}
			}
			if (thisSub.front().x + curtex1->xsize>bigTexX) {
				thisSub.clear();
				continue;
			}
			if(thisSub.front().y+curtex1->ysize>maxy){
				thisSub.pop_front();
				continue;
			}
			// ok found space for us
			foundx=thisSub.front().x;
			foundy=thisSub.front().y;
			done=true;

			if (thisSub.front().y + curtex1->ysize<maxy){
				nextSub.push_back(int2(thisSub.front().x, thisSub.front().y + curtex1->ysize));
			}

			thisSub.front().x += curtex1->xsize;
			while ((thisSub.size() > 1) && (thisSub.front().x >= (++thisSub.begin())->x)) {
				(++thisSub.begin())->x = thisSub.front().x;
				thisSub.erase(thisSub.begin());
			}

		}
		for (int y = 0; y < curtex1->ysize; ++y) {
			for (int x = 0; x < curtex1->xsize; ++x) {
//				if(curtex1->mem[(y*curtex1->xsize+x)*4]==254 && curtex1->mem[(y*curtex1->xsize+x)*4+1]==0 && curtex1->mem[(y*curtex1->xsize+x)*4+2]==254){
//					bigtex1[((cury+y)*bigTexX+(curx+x))*4+3] = 0;
//				} else {
					for (int col = 0; col < 4; ++col) {
						bigtex1[(((foundy + y) * bigTexX + (foundx + x)) * 4) + col] = curtex1->mem[(((y * curtex1->xsize) + x) * 4) + col];
						bigtex2[(((foundy + y) * bigTexX + (foundx + x)) * 4) + col] = curtex2->mem[(((y * curtex1->xsize) + x) * 4) + col];
//					}
				}
			}
		}

		UnitTexture* unittex = new UnitTexture;

		unittex->xstart = (foundx + 0.5f) / (float)bigTexX;
		unittex->ystart = (foundy + 0.5f) / (float)bigTexY;
		unittex->xend = (foundx + curtex1->xsize - 0.5f) / (float)bigTexX;
		unittex->yend = (foundy + curtex1->ysize - 0.5f) / (float)bigTexY;
		textures[texfiles[a]->name] = unittex;

		curx += curtex1->xsize;
		delete texfiles[a];
	}

	glGenTextures(1, &atlas3do1);
	glBindTexture(GL_TEXTURE_2D, atlas3do1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_NEAREST*/);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8 ,bigTexX, bigTexY, 0, GL_RGBA, GL_UNSIGNED_BYTE, bigtex1);
	//glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bigTexX, bigTexY, GL_RGBA, GL_UNSIGNED_BYTE, bigtex1);

	glGenTextures(1, &atlas3do2);
	glBindTexture(GL_TEXTURE_2D, atlas3do2);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_NEAREST*/);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, bigTexX, bigTexY, 0, GL_RGBA, GL_UNSIGNED_BYTE, bigtex2);
	//glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8, bigTexX, bigTexY, GL_RGBA, GL_UNSIGNED_BYTE, bigtex2);


//	CBitmap save(tex, bigTexX, bigTexY);
//	save.Save("unittex-1x.jpg");

	UnitTexture* t = new UnitTexture();
	t->xstart = 0.0f;
	t->ystart = 0.0f;
	t->xend = 1.0f;
	t->yend = 1.0f;
	textures["___dummy___"] = t;

	delete[] bigtex1;
	delete[] bigtex2;
}
Beispiel #28
0
bool CKeySet::Parse(const std::string& token)
{
	Reset();

	std::string s = StringToLower(token);

	// parse the modifiers
	while (!s.empty()) {
		     if (ParseModifier(s, "up+",    "u+")) { modifiers |= KS_RELEASE; }
		else if (ParseModifier(s, "any+",   "*+")) { modifiers |= KS_ANYMOD; }
		else if (ParseModifier(s, "alt+",   "a+")) { modifiers |= KS_ALT; }
		else if (ParseModifier(s, "ctrl+",  "c+")) { modifiers |= KS_CTRL; }
		else if (ParseModifier(s, "meta+",  "m+")) { modifiers |= KS_META; }
		else if (ParseModifier(s, "shift+", "s+")) { modifiers |= KS_SHIFT; }
		else {
			break;
		}
	}

#ifdef DISALLOW_RELEASE_BINDINGS
	modifiers &= ~KS_RELEASE;
#endif
	
	// remove ''s, if present
	if ((s.size() >= 2) && (s[0] == '\'') && (s[s.size() - 1] == '\'')) {
		s = s.substr(1, s.size() - 2);
	}

	if (s.find("0x") == 0) {
		const char* start = (s.c_str() + 2);
		char* end;
		key = strtol(start, &end, 16);
		if (end == start) {
			Reset();
			LOG_L(L_ERROR, "KeySet: Bad hex value: %s", s.c_str());
			return false;
		}
		if (key >= SDLK_LAST) {
			Reset();
			LOG_L(L_ERROR, "KeySet: Hex value out of range: %s", s.c_str());
			return false;
		}
	}
	else {
		key = keyCodes->GetCode(s);
		if (key < 0) {
			Reset();
			LOG_L(L_ERROR, "KeySet: Bad keysym: %s", s.c_str());
			return false;
		}
	}
	
	if (keyCodes->IsModifier(key)) {
		modifiers |= KS_ANYMOD;
	}

	if (AnyMod()) {
		ClearModifiers();
	}
	
	return true;
}
Beispiel #29
0
bool CRealTextParser::ExtractTag(wstring& p_rszLine, Tag& p_rTag)
{
	if (p_rszLine.length() < 2 || p_rszLine.at(0) != '<') {
		if (m_bTryToIgnoreErrors) {
			size_t iTempPos = p_rszLine.find_first_of('<');

			if (iTempPos != wstring::npos) {
				p_rszLine = p_rszLine.substr(iTempPos);

				if (p_rszLine.length() < 2) {
					return false;
				}
			}

		} else {
			return false;
		}
	}

	unsigned int iPos = 1;

	// skip comments
	if (p_rszLine.at(iPos) == '!') {
		p_rTag.m_bComment = true;

		wstring szComment;
		GetString(p_rszLine, iPos, szComment, L">");
		p_rTag.m_szName = szComment;

		++iPos; // Skip >
		p_rszLine = p_rszLine.substr(iPos);
		return true;
	} else {
		p_rTag.m_bComment = false;
	}

	if (!SkipSpaces(p_rszLine, iPos)) {
		return false;
	}

	if (p_rszLine.at(iPos) == '/') {
		p_rTag.m_bOpen = false;
		p_rTag.m_bClose = true;
		++iPos;
	} else {
		p_rTag.m_bOpen = true;
		p_rTag.m_bClose = false;
	}

	if (!GetString(p_rszLine, iPos, p_rTag.m_szName, L"\r\n\t />")) {
		return false;
	}

	p_rTag.m_szName = StringToLower(p_rTag.m_szName);

	if (!GetAttributes(p_rszLine, iPos, p_rTag.m_mapAttributes)) {
		return false;
	}

	if (p_rszLine.at(iPos) == '/') {
		++iPos;
		p_rTag.m_bClose = true;
	}

	if (p_rszLine.at(iPos) == '>') {
		++iPos;
		p_rszLine = p_rszLine.substr(iPos);
		return true;
	} else {
		if (m_bTryToIgnoreErrors) {
			size_t iTempPos = p_rszLine.find_first_of('>');

			if (iTempPos != wstring::npos) {
				if (iTempPos - 1 >= p_rszLine.length()) {
					return false;
				}

				p_rszLine = p_rszLine.substr(iTempPos + 1);
				return true;
			} else {
				return false;
			}

		} else {
			return false;
		}
	}
}
Beispiel #30
0
/** Constructor **/
Symbol::Symbol(Type_T type, std::string id, std::shared_ptr<Token> value,std::shared_ptr<AsmBlock> block): 
Type(type), ID(StringToLower(id)), Value(value), Reserved(false), Block(block), Temporary(false)
{
	//...
}