WorldEdit unlimeded blocks setzen?

  • Hallo Leute
    WorldEdit ist ein Programm um die Welten durch befehle zu bearbeiten.
    Der einfachste Befehl ist dort der "//set [Block]:[Data]" Befehl
    Diesen nutzen wir auf dem server sehr oft... wenn eine zu große Region makiert wurde hat der server nicht genug speicher um diese setzen zu können..


    Auf grund dessen möchte ich diesen befehl nun so ändern dass man damit unentlich viele blöcke setzen kann..
    Der Basis Befehl siet so aus:


    Nun ja, die Programmierer unter euch sehen schon warum es zu crashs kommt oder? xD


    Warum ich es hier öffentlich hin schreibe? Ich möchte einfach mal zeigen was ich denn so mache.
    Und damit ihr mir helfen könnt xD ich habe bisher nur alles theoretisch geplant, wie es denn so läuft weiß ich nicht...


    Nun meine Grund Idee um dieses Problem zu lösen:
    Alle Blöcke die darin enthalten sind in einer liste speichern und block für block diese abarbeiten mit einem Bukkit Scheduler der jeden Tick "100" Blöcke setzt.
    Theoretisch kann man nun beim aufbauen der zu setzenden blöcke zugucken und durch einen weiteren befehl diesen aufbau abbrechen...


    Also einen Neuen Befehl hinzufügen um das setzen abbrechen zu können.
    Mal sehen was WE damit in der Wirklichkeit raus macht xD


    Oder hat jemand eine Idee die noch einfacher geht?
    Performanter?
    Schneller muss es nicht mal gehen, hierbei geht es darum das der Server nicht crashen kann durch WE arbeiten.


    Kleiner

    Technischer Administrator, Entwicklungsleiter und Leiter des Let's Mine Minecraft Community Server Projektes
    KleinCrafter

  • Was mir am Rande auffällt:
    Der Block bei <Vector>(minX, minY, minZ) wird, dank Preinkrementation in deinem Schleifenkopf, nie gesetzt werden.


    Korrigiere: alle Blöcke die auf einer der Achsen bei minX, minY oder minZ liegen :grinning_squinting_face:


    Vergesst das - bei einer for-Schleife wird der hintere Block immer danach erst ausgeführt.

    2 Mal editiert, zuletzt von c_kodiert ()

  • Vielleicht eine dumme Frage:
    Wieso unbedingt 3 For-Schleifen für CuboidRegion aber nur eine foreach für alle anderen, anstatt einfach für alles foreach zu verwenden ?

  • Nur so als info, das was ich oben reingestelt habe ist der originale code von WorldEdit, ohne änderungen.
    Ich habe nur diesen teiel hochgeladen, weiel er CuboidRegionen setzt, poly und cyl regionen werden noch umständlicher gehandhabt...
    Zeile 1135


    Kleiner

    Technischer Administrator, Entwicklungsleiter und Leiter des Let's Mine Minecraft Community Server Projektes
    KleinCrafter

  • Achso, ja habe ich .. leider passiert nüx -.- er füht denn scheduller zwar aus aber er ändert keine blöcke .. ich denke mal das WE mit einer session arbeitet die zu früh beendet wird.. um mich darein zu lesen und das so zu ändern das es läuft dauert mir zu lange und ich arbeiter erstmal die restlichen sachen ab.. müssen sie die läute ebend mit WE zügeln :winking_face:


    Aber ich kann ja mal einen eigenen befehl einfügen oO
    Hmm, ja das mache ich doch gleich mal, selber setzen und nicht die funktion von WE nehmen, mal sehen was daraus wird...


    //edit
    xD Habe es geschaft es zeit versetzt zu setzen, leider ohne undo / redo funktion xD code werde ich am wochenende posten, bis dahin werde ich noch gucken ob es besser ist oder nicht.. (was passiert wohl wenn ich ausversehen mal 10K x 10K makiere? xD ich werde es morgen testen xD


    Kleiner

    Technischer Administrator, Entwicklungsleiter und Leiter des Let's Mine Minecraft Community Server Projektes
    KleinCrafter

  • Nicht wenn man das so aufteilt, dass er von unten nach oben arbeitet, oder?
    Dann landet neuer Gravel doch auf dem schon existierenden und dann gibts auch kein Problem :winking_face:


    Zumindest stelle ich mir das so vor :grinning_face_with_smiling_eyes:

  • Oder es werden einfach keine Blockupdates generiert und der Kies und der Sand bekommen gar nicht erst die Möglichkeit mitzukriegen, dass sie in der Luft hängen. So ist es meiner Meinung nach auch gerade und es gibt nur wenige Gründe, das zu ändern.

    Code
    ┌──┐ ┌┐  ┌┐ ┌┐   ┌─┐                         ┌┐
    │┌┐│ ││  └┘┌┘└┐  │┌┘                         ││
    │└┘│ │└─┐┌┐└┐┌┘ ┌┘└┐┌──┐┌─┐┌───┐┌┐┌┐┌───┐┌─┐ ││
    │┌┐│ │┌┐│││ ││  └┐┌┘│┌┐││┌┘│ ─ ││└┘││ ─ ││┌┘ └┘
    │└┘│ │└┘│││ │└┐  ││ │└┘│││ │ ──┤└┐┌┘│ ──┤││  ┌┐
    └──┘ └──┘└┘ └─┘  └┘ └──┘└┘ └───┘ └┘ └───┘└┘  └┘
  • Echt? Auf dem server gibt es keine Blockupdates? O.o
    Dann würde das einiges erklären, weil ich dachte, dass meine Sachen aus eigener Verpeiltheit nicht geklappt haben... :grinning_squinting_face:

  • Ömm input = minimaler und maximaler punkt, ich dfange mit dem minimum an und höre beim maximum auf.
    Keine probleme mit sand / gravel da dieser von unten nach oben schicht für schicht gesetzt wird.


    Ich habe dafür aktuell neue commands erstellt, bin aber noch nicht zufrieden mit der arbeitsweise..
    Werde es morgen überarbeiten damit der server es in einer akzeptablen zeit hinbekommt.
    Imoment siet es so aus:

    Code
    /**     * Sets all the blocks inside a region to a certain block type.     *     * @param region     * @param pattern     * @return number of blocks affected     * @throws MaxChangedBlocksException     */    public int setBlocks(Region region, Pattern pattern, LocalSession session, LocalPlayer player, EditSession editSession) throws MaxChangedBlocksException {    	BlockScheduler bs = new BlockScheduler(region, pattern, session, player, editSession);    	int tmp = Bukkit.getScheduler().scheduleSyncRepeatingTask(Bukkit.getPluginManager().getPlugin("WorldEdit"), bs, 0, 5);    	bs.setID(tmp);    	return tmp;    }    private class BlockList {    	public int x, y, z;    	public BlockList(int x, int y, int z) {    		this.x = x;    		this.y = y;    		this.z = z;		}    }    private class BlockScheduler implements Runnable {    	private int id = 0;    	private Region region;    	private Pattern pattern;    	private LocalSession session;    	private LocalPlayer player;    	private EditSession editSession;    	private long count = 0;    	private ArrayList<BlockList> bl = new ArrayList<BlockList>();    	public BlockScheduler(Region region, Pattern pattern, LocalSession session, LocalPlayer player, EditSession editSession) throws MaxChangedBlocksException {    		this.region = region;    		this.pattern = pattern;    		this.session = session;    		this.player = player;    		this.editSession = editSession;            Vector min = region.getMinimumPoint();            Vector max = region.getMaximumPoint();            int minX = min.getBlockX();            int minY = min.getBlockY();            int minZ = min.getBlockZ();            int maxX = max.getBlockX();            int maxY = max.getBlockY();            int maxZ = max.getBlockZ();            for (int x = minX; x <= maxX; ++x) {                for (int y = minY; y <= maxY; ++y) {                    for (int z = minZ; z <= maxZ; ++z) {                        bl.add(new BlockList(x, y, z));                    }                }            }		}    	public void setID(int id) {    		this.id = id;    	}		@Override		public void run() {			for(int tick = 0; tick <= 1000; tick++) {				if (bl.size() <= 0) {					finish();					return;				}				BlockList bl = this.bl.get(0);                Vector pt = new Vector(bl.x, bl.y, bl.z);                world.checkLoadedChunk(pt);                if (region.getWorld().setBlock(pt, pattern.next(pt), true)) {                	++count;                }                this.bl.remove(0);			}			if (this.bl.size() <= 0) {				finish();				return;			}		}		public void finish() {			player.printDebug("Es wurden " + count + " Bl\u00F6cke ge\u00E4ndert.");			Bukkit.getScheduler().cancelTask(id);		}    }



    //TODO:
    selbstgeschriebene Liste die mit einem long arbeitet
    Eine statische liste die alle SetTime befehler hinereinander abarbeitet.
    Einen befehl hinzufügen, der denn stand der prozedur abfragt
    Einen befehl hinzufügen, der anzeigt wieviele prozesse


    Kleiner

    Technischer Administrator, Entwicklungsleiter und Leiter des Let's Mine Minecraft Community Server Projektes
    KleinCrafter

  • @ UndeaD_Bot: Was ich meinte war, dass beim Setzen und Kopieren per WorldEdit keine neuen Blockupdates generiert werden. Die Daten werden wie sie sind an eine andere Stelle geschrieben. Die "normalen" Blockupdates gibt es natürlich. Ohne sie würden z.B. auch Wasser- und Lavaflüsse nicht funktionieren, ganz zu schweigen von den ganzen Pistontüren, die überall verbaut sind.

    Code
    ┌──┐ ┌┐  ┌┐ ┌┐   ┌─┐                         ┌┐
    │┌┐│ ││  └┘┌┘└┐  │┌┘                         ││
    │└┘│ │└─┐┌┐└┐┌┘ ┌┘└┐┌──┐┌─┐┌───┐┌┐┌┐┌───┐┌─┐ ││
    │┌┐│ │┌┐│││ ││  └┐┌┘│┌┐││┌┘│ ─ ││└┘││ ─ ││┌┘ └┘
    │└┘│ │└┘│││ │└┐  ││ │└┘│││ │ ──┤└┐┌┘│ ──┤││  ┌┐
    └──┘ └──┘└┘ └─┘  └┘ └──┘└┘ └───┘ └┘ └───┘└┘  └┘
  • Bin ned sicher ob ich das richtig verstanden habe aber ich glaub dieses Plugin ist exakt das was du haben willst @KleinCrafter.
    https://www.spigotmc.org/resources/asyncworldedit.327/


    Das Plugin wandelt "Aufträge" wie //set 1 bei einer großen Fläche in mehrere Pakete um und sendet diese nacheinander an den Server.
    Zusätzlich zeigt das Plugin auch noch an wieviele Blöcke pro Sekunde grade gesetzt werden (Kann über config auch eingestellt werden afaik)


    Vielleicht kannste da ja was abkupfern :face_with_tongue: