Änderungsschutz

Angeregt durch die Frage eines Multiplayermapers habe ich ein Script gemacht, in dem man das, was auf der Map steht, in Grenzen schützen kann.

Es wird eine Funktion erzeugt, die, wenn sie im Script aufgerufen wird, prüft ob irgendwelche Dinge verändert wurden. Wenn ja, wird es zurückgesetzt


Die Prüfung hat zwei Möglichkeiten.

Alles was da sein muss, muss in das table schutzTable.
Alles was da sein muss und nichts neues mehr dazu auf die Map gestellt werden darf, muss in das table schutzTable2.
Hier darf nicht rein, wovon mehr als 16 auf der Map sind, sonst würde das erste Laden zu lange dauern.
Diese beiden Table liegen in einer Datei, die SchutzTable.lua heißt:

schutzTable={"Wall"}
schutzTable2={"XD_VillageCenter","PB_VillageCenter1","PB_VillageCenter2","PB_VillageCenter3","PB_Headquarters3","PB_Headquarters2","PB_Headquarters1","PB_DarkTower3","PB_DarkTower2","PB_DarkTower1"}

Diese kann man nach belieben besetzten.
Beim Start des nachfolgenden Scripts mit : lua AenderSchutz.lua „MeineMap.s5x“ oder lua AenderSchutz.lua „MeineMap“
wird eine Datei erzeugt, die den Namen MeineMapSchutz.lua hat. Dort ist dann eine Funktion drin, die, wenn man sie aufruft, alles in den ursprünglichen Stand versetzt. (am Anfang)
Du brauchst man :


alles ins Verzeichnis wo die Map liegt.

assert( arg[1], "lua AenderSchutz.lua <mapfile>" )
if string.find(arg[1],"%.") then
	arg[1] = string.sub(arg[1] ,1 , string.find(arg[1],"%.")-1)
end
os.execute( 'EntityOut.exe "' .. arg[1]..".s5x" .. '" > EntityOut.tmp' );
local handle = io.output( arg[1].."Schutz.lua" );
handle:write( "function MapSchutz()\n" );
handle:write( "\tlocal myEntities={\n" );
local zeile="\t"
myEntities={}
dofile("SchutzTable.lua")
for line in io.lines( "EntityOut.tmp" ) do
    if string.sub(line,4) ~= "Type" then
        local _, _, entitytype, posx, posy, orientation, player, name = string.find( line, "^([^,]+),([%d%.][^,]*),([%d%.][^,]*),([%d%.][^,]*),(%d),(.*)$" );
        table.insert(myEntities,{entitytype, posx, posy, orientation, player, name})
    end
end
for i = 1, table.getn(myEntities) do
    for j = 1, table.getn(schutzTable) do
    if myEntities[i][1] then
        if string.find(myEntities[i][1], schutzTable[j]) then
            zeile=zeile.."{X="..tonumber(myEntities[i][2])..", Y="..tonumber(myEntities[i][3])..",O="..tonumber(myEntities[i][4])..",P="..myEntities[i][5]..",N=\""..myEntities[i][6].."\""..",T=\""..myEntities[i][1].."\"},"
            if string.len(zeile) > 100 then
                handle:write( zeile.."\n" );
                zeile="\t";
            end
        end
    end
    end
end
handle:write( zeile.."}\n" );
zeile="\t"
handle:write( "\tlocal myEntities2Maske={" );
for i = 1,table.getn(schutzTable2) do
    handle:write( "\""..schutzTable2[i].."\"," );
end
handle:write( "}\n" );
handle:write( "\tlocal myEntities2={\n" );
for i = 1, table.getn(myEntities) do
    for j = 1, table.getn(schutzTable2) do
    if myEntities[i][1] then
        if string.find(myEntities[i][1], schutzTable2[j]) then
            zeile=zeile.."{X="..tonumber(myEntities[i][2])..", Y="..tonumber(myEntities[i][3])..",O="..tonumber(myEntities[i][4])..",P="..myEntities[i][5]..",N=\""..myEntities[i][6].."\""..",T=\""..myEntities[i][1].."\"},"
            if string.len(zeile) > 100 then
                handle:write( zeile.."\n" );
                zeile="\t";
            end
        end
    end
    end
end
handle:write( zeile.."}\n" );
handle:write( [[
	for i  = 1,table.getn(myEntities) do
		local nID=Logic.GetEntityAtPosition(myEntities[i].X,myEntities[i].Y)
		if not nID then
			nID=Logic.CreateEntity(Entities[myEntities[i].T],myEntities[i].X,myEntities[i].Y,myEntities[i].O,myEntities[i].P)
			if myEntities[i].N ~= "" then
				SetEntityName(nID,myEntities[i].N)
			end
		elseif Logic.GetEntityOrientation(nID) ~= myEntities[i].O then
			DestroyEntity(nID)
			nID=Logic.CreateEntity(Entities[myEntities[i].T],myEntities[i].X,myEntities[i].Y,myEntities[i].O,myEntities[i].P)
			if myEntities[i].N ~= "" then
				SetEntityName(nID,myEntities[i].N)
			end
		elseif GetPlayer(nID) ~= myEntities[i].P then
			ChangePlayer(nID,myEntities[i].P)
		end
	end
	local nSize=Logic.WorldGetSize()
	local nMitte=nSize/2
	nSize=math.sqrt(nSize^2+nSize^2)/2
	local jetztEntities={}
	for i = 1,table.getn(myEntities2Maske) do
		local data={Logic.GetEntitiesInArea(Entities[myEntities2Maske[i] ],nMitte,nMitte,nSize,16)}
		table.remove(data,1)
		for j = 1,table.getn(data) do
			table.insert(jetztEntities,{Entities[myEntities2Maske[i] ],data[j],Logic.GetEntityOrientation(data[j]),GetPlayer(data[j]),GetPosition(data[j])})
		end
	end
	for i = table.getn(jetztEntities),1,-1  do
		for j = table.getn(myEntities2),1,-1  do
			if jetztEntities[i][1] == Entities[myEntities2[j].T] then
				if jetztEntities[i][5].X == myEntities2[j].X and jetztEntities[i][5].Y == myEntities2[j].Y then
					if jetztEntities[i][3] ~= myEntities2[j].O then
						DestroyEntity(jetztEntities[i][2])
						local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P)
						if myEntities2[j].N ~= "" then
							SetEntityName(nID,myEntities2[j].N)
						end
					end
					if jetztEntities[i][4] ~= myEntities2[j].P then
						ChangePlayer(jetztEntities[i][2],myEntities2[j].P)
					end
					table.remove(jetztEntities,i)
					table.remove(myEntities2,j)
					break
				end
			end
		end
	end
	for i =1,table.getn(jetztEntities) do
		DestroyEntity(jetztEntities[i][2])
	end
	for j =1,table.getn(myEntities2) do
		if myEntities2[j].T == "XD_VillageCenter" then 
			local nID=Logic.GetEntityAtPosition(myEntities[j].X,myEntities[j].Y)
			if nID then
				if not string.find(Logic.GetEntityTypeName(Logic.GetEntityType(nID)),"Village") then
					-- Villagecenter wurde gelöscht
				end
			else
				local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P)
				if myEntities2[j].N ~= "" then
					SetEntityName(nID,myEntities2[j].N)
				end
			end
		else
			local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P)
			if myEntities2[j].N ~= "" then
				SetEntityName(nID,myEntities2[j].N)
			end
		end
	end
end
]]);handle:close();
os.execute( "del EntityOut.tmp" );